Skip to content

Commit

Permalink
Support precomplie project of vmbridge (#3122)
Browse files Browse the repository at this point in the history
* complete precompile cross-vm call

* solve a bug

* solve bug

* change precompile msg dispatch

* complete precompile cross-vm query

* change go mod

* add precompile.json

* finish unit test and solve two bug

* make unit test pass

* resolve review suggestion

* update eth dependency

* make unit test pass

* complete precompile cross-vm call

* update go.mod
  • Loading branch information
BananaLF authored May 12, 2023
1 parent b3b958c commit ec80d21
Show file tree
Hide file tree
Showing 40 changed files with 2,974 additions and 16 deletions.
2 changes: 1 addition & 1 deletion app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -611,7 +611,7 @@ func NewOKExChainApp(
wasmModule := wasm.NewAppModule(*app.marshal, &app.WasmKeeper)
app.WasmPermissionKeeper = wasmModule.GetPermissionKeeper()
app.VMBridgeKeeper = vmbridge.NewKeeper(app.marshal, app.Logger(), app.EvmKeeper, app.WasmPermissionKeeper, app.AccountKeeper, app.BankKeeper)

app.EvmKeeper.SetCallToCM(vmbridge.PrecompileHooks(app.VMBridgeKeeper))
// Set EVM hooks
app.EvmKeeper.SetHooks(
evm.NewMultiEvmHooks(
Expand Down
3 changes: 2 additions & 1 deletion dev/wasm/vmbridge-erc20/src/contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,8 @@ fn try_transfer(
Ok(Response::new()
.add_attribute("action", "transfer")
.add_attribute("sender", info.sender)
.add_attribute("recipient", recipient))
.add_attribute("recipient", recipient)
.set_data(b"the result wasm contract data"))
}

fn try_transfer_from(
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ replace (
github.com/buger/jsonparser => github.com/buger/jsonparser v1.0.0 // imported by nacos-go-sdk, upgraded to v1.0.0 in case of a known vulnerable bug
github.com/confio/ics23/go => github.com/cosmos/cosmos-sdk/ics23/go v0.8.0
github.com/cosmos/gorocksdb => github.com/okex/grocksdb v1.6.45-okc2
github.com/ethereum/go-ethereum => github.com/okex/go-ethereum v1.10.8-okc1
github.com/ethereum/go-ethereum => github.com/okex/go-ethereum v1.10.8-okc2
github.com/gogo/protobuf => github.com/regen-network/protobuf v1.3.3-alpha.regen.1
github.com/keybase/go-keychain => github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4
github.com/tendermint/go-amino => github.com/okex/go-amino v0.15.1-okc4
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -738,8 +738,8 @@ github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=
github.com/okex/go-amino v0.15.1-okc4 h1:+fl5ecyI15QZ7RAqgvlAnFrafCMcY9tnEYwtJ2djZoA=
github.com/okex/go-amino v0.15.1-okc4/go.mod h1:TQU0M1i/ImAo+tYpZi73AU3V/dKeCoMC9Sphe2ZwGME=
github.com/okex/go-ethereum v1.10.8-okc1 h1:s/fG9BgtL6qf1TcXYJeBCcN9AS6jR1zW5UywDJstqLo=
github.com/okex/go-ethereum v1.10.8-okc1/go.mod h1:pJNuIUYfX5+JKzSD/BTdNsvJSZ1TJqmz0dVyXMAbf6M=
github.com/okex/go-ethereum v1.10.8-okc2 h1:179aFei/Fr3Fx+CK+6s8g7k+2BYcZtIenSgeBO0DK70=
github.com/okex/go-ethereum v1.10.8-okc2/go.mod h1:pJNuIUYfX5+JKzSD/BTdNsvJSZ1TJqmz0dVyXMAbf6M=
github.com/okex/grocksdb v1.6.45-okc2 h1:JuUg2NcAFHZn78+xANcEKn9bcuF0tX8Jx3iMFfPnAEQ=
github.com/okex/grocksdb v1.6.45-okc2/go.mod h1:+/BHUY+mT0tbaVXwO2wTtD9eytazyw1W5n2O7AGyXZA=
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
Expand Down
78 changes: 78 additions & 0 deletions libs/cosmos-sdk/store/cachekv/store.go
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,59 @@ func (store *Store) Delete(key []byte) {
store.setCacheValue(key, nil, true, true)
}

// Implements Cachetypes.KVStore.
func (store *Store) WriteWithSnapshotWSet() types.SnapshotWSet {
// if parent is cachekv.Store, we can write kv more efficiently
if pStore, ok := store.parent.(*Store); ok {
return store.writeToCacheKvWithSnapShotWSet(pStore)
}

store.mtx.Lock()
defer store.mtx.Unlock()

// We need a copy of all of the keys.
// Not the best, but probably not a bottleneck depending.
keys := make([]string, len(store.dirty))
index := 0
for key, _ := range store.dirty {
keys[index] = key
index++

}

sort.Strings(keys)
store.preWrite(keys)

store.StartTiming()

swset := types.NewSnapShotWSet()
// TODO: Consider allowing usage of Batch, which would allow the write to
// at least happen atomically.
for _, key := range keys {
//set prevalue
swset.Write[key] = types.RevertWriteChange{PrevValue: store.parent.Get([]byte(key))}
cacheValue := store.dirty[key]
switch {
case cacheValue.deleted:
store.parent.Delete([]byte(key))
case cacheValue.value == nil:
// Skip, it already doesn't exist in parent.
default:
store.parent.Set([]byte(key), cacheValue.value)
}
}

// Clear the cache
store.clearCache()
store.EndTiming(trace.FlushCache)
return swset
}

// Implements Cachetypes.KVStore.
func (store *Store) RevertDBWithSnapshotRWSet(set types.SnapshotWSet) {
types.RevertSnapshotWSet(store, set)
}

// Implements Cachetypes.KVStore.
func (store *Store) Write() {
// if parent is cachekv.Store, we can write kv more efficiently
Expand Down Expand Up @@ -233,6 +286,31 @@ func (store *Store) writeToCacheKv(parent *Store) {
store.clearCache()
}

// writeToCacheKv will write cached kv to the parent Store, then clear the cache.
func (store *Store) writeToCacheKvWithSnapShotWSet(parent *Store) types.SnapshotWSet {
store.mtx.Lock()
defer store.mtx.Unlock()

// TODO: Consider allowing usage of Batch, which would allow the write to
// at least happen atomically.
swset := types.NewSnapShotWSet()
for key, cacheValue := range store.dirty {
swset.Write[key] = types.RevertWriteChange{PrevValue: store.parent.Get([]byte(key))}
switch {
case cacheValue.deleted:
parent.Delete(amino.StrToBytes(key))
case cacheValue.value == nil:
// Skip, it already doesn't exist in parent.
default:
parent.Set(amino.StrToBytes(key), cacheValue.value)
}
}

// Clear the cache
store.clearCache()
return swset
}

func (store *Store) clearCache() {
// https://github.com/golang/go/issues/20138
for key := range store.dirty {
Expand Down
56 changes: 56 additions & 0 deletions libs/cosmos-sdk/store/cachekv/store_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,62 @@ func TestCacheKVStore(t *testing.T) {
require.Empty(t, mem.Get(keyFmt(1)), "Expected `key1` to be empty")
}

func TestStore_WriteWithSnapShotWSet(t *testing.T) {
mem := dbadapter.Store{DB: dbm.NewMemDB()}
st := cachekv.NewStore(mem)

require.Empty(t, st.Get(keyFmt(1)), "Expected `key1` to be empty")

// put something in mem and in cache
mem.Set(keyFmt(1), valFmt(1))
st.Set(keyFmt(1), valFmt(1))
require.Equal(t, valFmt(1), st.Get(keyFmt(1)))

// update it in cache, shoudn't change mem
st.Set(keyFmt(1), valFmt(2))
require.Equal(t, valFmt(2), st.Get(keyFmt(1)))
require.Equal(t, valFmt(1), mem.Get(keyFmt(1)))

// write it. should change mem
snapshot := st.WriteWithSnapshotWSet()
require.Equal(t, valFmt(2), mem.Get(keyFmt(1)))
require.Equal(t, valFmt(2), st.Get(keyFmt(1)))
require.Equal(t, 1, len(snapshot.Write))
require.Equal(t, snapshot.Write[string(keyFmt(1))].PrevValue, valFmt(1))

// more writes and checks
snapshot = st.WriteWithSnapshotWSet()
require.Equal(t, 0, len(snapshot.Write))
snapshot = st.WriteWithSnapshotWSet()
require.Equal(t, 0, len(snapshot.Write))
require.Equal(t, valFmt(2), mem.Get(keyFmt(1)))
require.Equal(t, valFmt(2), st.Get(keyFmt(1)))

// make a new one, check it
st = cachekv.NewStore(mem)
require.Equal(t, valFmt(2), st.Get(keyFmt(1)))

// make a new one and delete - should not be removed from mem
st = cachekv.NewStore(mem)
st.Delete(keyFmt(1))
require.Empty(t, st.Get(keyFmt(1)))
require.Equal(t, mem.Get(keyFmt(1)), valFmt(2))

// Write. should now be removed from both
snapshot = st.WriteWithSnapshotWSet()
require.Equal(t, 1, len(snapshot.Write))
require.Equal(t, snapshot.Write[string(keyFmt(1))].PrevValue, valFmt(2))
require.Empty(t, st.Get(keyFmt(1)), "Expected `key1` to be empty")
require.Empty(t, mem.Get(keyFmt(1)), "Expected `key1` to be empty")

// insert new
st.Set(keyFmt(1), valFmt(1))
snapshot = st.WriteWithSnapshotWSet()
require.Equal(t, 1, len(snapshot.Write))

require.Nil(t, snapshot.Write[string(keyFmt(1))].PrevValue)
}

func TestCacheKVStoreNoNilSet(t *testing.T) {
mem := dbadapter.Store{DB: dbm.NewMemDB()}
st := cachekv.NewStore(mem)
Expand Down
30 changes: 30 additions & 0 deletions libs/cosmos-sdk/store/cachemulti/store.go
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,36 @@ func (cms Store) Write() {
}
}

// Write calls Write on each underlying store.
func (cms Store) WriteWithSnapshotWSet() types.SnapshotWSet {
panic("not support ")
}

func (cms Store) RevertDBWithSnapshotRWSet(set types.SnapshotWSet) {
panic("not support ")
}

func (cms Store) WriteGetMultiSnapshotWSet() types.MultiSnapshotWSet {
multiSet := types.NewMultiSnapshotWSet()
multiSet.Root = cms.db.WriteWithSnapshotWSet()
for key, store := range cms.stores {
multiSet.Stores[key] = store.WriteWithSnapshotWSet()
}
return multiSet
}

func (cms Store) RevertDBWithMultiSnapshotRWSet(set types.MultiSnapshotWSet) {
types.RevertSnapshotWSet(cms.db, set.Root)
for key, store := range cms.stores {
if vSet, ok := set.Stores[key]; !ok {
panic(fmt.Errorf("RevertDBWithMultiSnapshotRWSet store %s but MultiSnapshotWSet have not", key.String()))
} else {
store.RevertDBWithSnapshotRWSet(vSet)
}

}
}

func (cms Store) IteratorCache(isdirty bool, cb func(key string, value []byte, isDirty bool, isDelete bool, storeKey types.StoreKey) bool, sKey types.StoreKey) bool {
for key, store := range cms.stores {
if !store.IteratorCache(isdirty, cb, key) {
Expand Down
Loading

0 comments on commit ec80d21

Please sign in to comment.