Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Contract Migrate Version #540

Merged
merged 9 commits into from
Jun 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions ibc_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -302,6 +302,7 @@ func TestAnalyzeCode(t *testing.T) {
require.NoError(t, err)
require.False(t, report.HasIBCEntryPoints)
require.Equal(t, "", report.RequiredCapabilities)
require.Equal(t, uint64(42), *report.ContractMigrateVersion)

// Store IBC contract
wasm2, err := os.ReadFile(IBC_TEST_CONTRACT)
Expand All @@ -313,6 +314,7 @@ func TestAnalyzeCode(t *testing.T) {
require.NoError(t, err)
require.True(t, report2.HasIBCEntryPoints)
require.Equal(t, "iterator,stargate", report2.RequiredCapabilities)
require.Nil(t, report2.ContractMigrateVersion)
}

func TestIBCMsgGetChannel(t *testing.T) {
Expand Down
15 changes: 15 additions & 0 deletions internal/api/bindings.h
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,14 @@ typedef struct UnmanagedVector {
uintptr_t cap;
} UnmanagedVector;

/**
* A version of `Option<u64>` that can be used safely in FFI.
*/
typedef struct OptionalU64 {
bool is_some;
uint64_t value;
} OptionalU64;

/**
* The result type of the FFI function analyze_code.
*
Expand All @@ -217,6 +225,13 @@ typedef struct AnalysisReport {
* This is never None/nil.
*/
struct UnmanagedVector required_capabilities;
/**
* The migrate version of the contract.
* This is None if the contract does not have a migrate version and the `migrate` entrypoint
* needs to be called for every migration (if present).
* If it is `Some(version)`, it only needs to be called if the `version` increased.
*/
struct OptionalU64 contract_migrate_version;
} AnalysisReport;

typedef struct Metrics {
Expand Down
8 changes: 5 additions & 3 deletions internal/api/lib.go
Original file line number Diff line number Diff line change
Expand Up @@ -161,10 +161,12 @@ func AnalyzeCode(cache Cache, checksum []byte) (*types.AnalysisReport, error) {
}
requiredCapabilities := string(copyAndDestroyUnmanagedVector(report.required_capabilities))
entrypoints := string(copyAndDestroyUnmanagedVector(report.entrypoints))

res := types.AnalysisReport{
HasIBCEntryPoints: bool(report.has_ibc_entry_points),
RequiredCapabilities: requiredCapabilities,
Entrypoints: strings.Split(entrypoints, ","),
HasIBCEntryPoints: bool(report.has_ibc_entry_points),
RequiredCapabilities: requiredCapabilities,
Entrypoints: strings.Split(entrypoints, ","),
ContractMigrateVersion: optionalU64ToPtr(report.contract_migrate_version),
}
return &res, nil
}
Expand Down
34 changes: 17 additions & 17 deletions internal/api/lib_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -305,7 +305,7 @@ func TestGetMetrics(t *testing.T) {
require.Equal(t, uint32(0), metrics.HitsMemoryCache)
require.Equal(t, uint32(1), metrics.HitsFsCache)
require.Equal(t, uint64(1), metrics.ElementsMemoryCache)
require.InEpsilon(t, 2832576, metrics.SizeMemoryCache, 0.25)
require.InEpsilon(t, 3700000, metrics.SizeMemoryCache, 0.25)

// Instantiate 2
msg2 := []byte(`{"verifier": "fred", "beneficiary": "susi"}`)
Expand All @@ -318,7 +318,7 @@ func TestGetMetrics(t *testing.T) {
require.Equal(t, uint32(1), metrics.HitsMemoryCache)
require.Equal(t, uint32(1), metrics.HitsFsCache)
require.Equal(t, uint64(1), metrics.ElementsMemoryCache)
require.InEpsilon(t, 2832576, metrics.SizeMemoryCache, 0.25)
require.InEpsilon(t, 3700000, metrics.SizeMemoryCache, 0.25)

// Pin
err = Pin(cache, checksum)
Expand All @@ -331,8 +331,8 @@ func TestGetMetrics(t *testing.T) {
require.Equal(t, uint32(2), metrics.HitsFsCache)
require.Equal(t, uint64(1), metrics.ElementsPinnedMemoryCache)
require.Equal(t, uint64(1), metrics.ElementsMemoryCache)
require.InEpsilon(t, 2832576, metrics.SizePinnedMemoryCache, 0.25)
require.InEpsilon(t, 2832576, metrics.SizeMemoryCache, 0.25)
require.InEpsilon(t, 3700000, metrics.SizePinnedMemoryCache, 0.25)
require.InEpsilon(t, 3700000, metrics.SizeMemoryCache, 0.25)

// Instantiate 3
msg3 := []byte(`{"verifier": "fred", "beneficiary": "bert"}`)
Expand All @@ -347,8 +347,8 @@ func TestGetMetrics(t *testing.T) {
require.Equal(t, uint32(2), metrics.HitsFsCache)
require.Equal(t, uint64(1), metrics.ElementsPinnedMemoryCache)
require.Equal(t, uint64(1), metrics.ElementsMemoryCache)
require.InEpsilon(t, 2832576, metrics.SizePinnedMemoryCache, 0.25)
require.InEpsilon(t, 2832576, metrics.SizeMemoryCache, 0.25)
require.InEpsilon(t, 3700000, metrics.SizePinnedMemoryCache, 0.25)
require.InEpsilon(t, 3700000, metrics.SizeMemoryCache, 0.25)

// Unpin
err = Unpin(cache, checksum)
Expand All @@ -363,7 +363,7 @@ func TestGetMetrics(t *testing.T) {
require.Equal(t, uint64(0), metrics.ElementsPinnedMemoryCache)
require.Equal(t, uint64(1), metrics.ElementsMemoryCache)
require.Equal(t, uint64(0), metrics.SizePinnedMemoryCache)
require.InEpsilon(t, 2832576, metrics.SizeMemoryCache, 0.25)
require.InEpsilon(t, 3700000, metrics.SizeMemoryCache, 0.25)

// Instantiate 4
msg4 := []byte(`{"verifier": "fred", "beneficiary": "jeff"}`)
Expand All @@ -379,7 +379,7 @@ func TestGetMetrics(t *testing.T) {
require.Equal(t, uint64(0), metrics.ElementsPinnedMemoryCache)
require.Equal(t, uint64(1), metrics.ElementsMemoryCache)
require.Equal(t, uint64(0), metrics.SizePinnedMemoryCache)
require.InEpsilon(t, 2832576, metrics.SizeMemoryCache, 0.25)
require.InEpsilon(t, 3700000, metrics.SizeMemoryCache, 0.25)
}

func TestInstantiate(t *testing.T) {
Expand All @@ -405,7 +405,7 @@ func TestInstantiate(t *testing.T) {
res, cost, err := Instantiate(cache, checksum, env, info, msg, &igasMeter, store, api, &querier, TESTING_GAS_LIMIT, TESTING_PRINT_DEBUG)
require.NoError(t, err)
requireOkResponse(t, res, 0)
assert.Equal(t, uint64(0x5088ea), cost.UsedInternally)
assert.Equal(t, uint64(0x540eb6), cost.UsedInternally)

var result types.ContractResult
err = json.Unmarshal(res, &result)
Expand Down Expand Up @@ -436,7 +436,7 @@ func TestExecute(t *testing.T) {
diff := time.Since(start)
require.NoError(t, err)
requireOkResponse(t, res, 0)
assert.Equal(t, uint64(0x5088ea), cost.UsedInternally)
assert.Equal(t, uint64(0x540eb6), cost.UsedInternally)
t.Logf("Time (%d gas): %s\n", cost.UsedInternally, diff)

// execute with the same store
Expand All @@ -449,7 +449,7 @@ func TestExecute(t *testing.T) {
res, cost, err = Execute(cache, checksum, env, info, []byte(`{"release":{}}`), &igasMeter2, store, api, &querier, TESTING_GAS_LIMIT, TESTING_PRINT_DEBUG)
diff = time.Since(start)
require.NoError(t, err)
assert.Equal(t, uint64(0x8be9c6), cost.UsedInternally)
assert.Equal(t, uint64(0x975216), cost.UsedInternally)
t.Logf("Time (%d gas): %s\n", cost.UsedInternally, diff)

// make sure it read the balance properly and we got 250 atoms
Expand Down Expand Up @@ -557,7 +557,7 @@ func TestExecuteCpuLoop(t *testing.T) {
diff := time.Since(start)
require.NoError(t, err)
requireOkResponse(t, res, 0)
assert.Equal(t, uint64(0x365a42), cost.UsedInternally)
assert.Equal(t, uint64(0x3d997e), cost.UsedInternally)
t.Logf("Time (%d gas): %s\n", cost.UsedInternally, diff)

// execute a cpu loop
Expand Down Expand Up @@ -786,7 +786,7 @@ func TestMultipleInstances(t *testing.T) {
require.NoError(t, err)
requireOkResponse(t, res, 0)
// we now count wasm gas charges and db writes
assert.Equal(t, uint64(0x4ffce0), cost.UsedInternally)
assert.Equal(t, uint64(0x53541c), cost.UsedInternally)

// instance2 controlled by mary
gasMeter2 := NewMockGasMeter(TESTING_GAS_LIMIT)
Expand All @@ -797,14 +797,14 @@ func TestMultipleInstances(t *testing.T) {
res, cost, err = Instantiate(cache, checksum, env, info, msg, &igasMeter2, store2, api, &querier, TESTING_GAS_LIMIT, TESTING_PRINT_DEBUG)
require.NoError(t, err)
requireOkResponse(t, res, 0)
assert.Equal(t, uint64(0x504dbc), cost.UsedInternally)
assert.Equal(t, uint64(0x53bbb4), cost.UsedInternally)

// fail to execute store1 with mary
resp := exec(t, cache, checksum, "mary", store1, api, querier, 0x4a20c2)
resp := exec(t, cache, checksum, "mary", store1, api, querier, 0x503f70)
require.Equal(t, "Unauthorized", resp.Err)

// succeed to execute store1 with fred
resp = exec(t, cache, checksum, "fred", store1, api, querier, 0x8ba826)
resp = exec(t, cache, checksum, "fred", store1, api, querier, 0x970662)
require.Equal(t, "", resp.Err)
require.Equal(t, 1, len(resp.Ok.Messages))
attributes := resp.Ok.Attributes
Expand All @@ -813,7 +813,7 @@ func TestMultipleInstances(t *testing.T) {
require.Equal(t, "bob", attributes[1].Value)

// succeed to execute store2 with mary
resp = exec(t, cache, checksum, "mary", store2, api, querier, 0x8bc8f6)
resp = exec(t, cache, checksum, "mary", store2, api, querier, 0x972c3c)
require.Equal(t, "", resp.Err)
require.Equal(t, 1, len(resp.Ok.Messages))
attributes = resp.Ok.Attributes
Expand Down
7 changes: 7 additions & 0 deletions internal/api/memory.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,13 @@ func copyAndDestroyUnmanagedVector(v C.UnmanagedVector) []byte {
return out
}

func optionalU64ToPtr(val C.OptionalU64) *uint64 {
if val.is_some {
return (*uint64)(&val.value)
webmaster128 marked this conversation as resolved.
Show resolved Hide resolved
}
return nil
}

// copyU8Slice copies the contents of an Option<&[u8]> that was allocated on the Rust side.
// Returns nil if and only if the source is None.
func copyU8Slice(view C.U8SliceView) []byte {
Expand Down
16 changes: 8 additions & 8 deletions lib_libwasmvm_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -285,7 +285,7 @@ func TestGetMetrics(t *testing.T) {
require.Equal(t, uint32(1), metrics.HitsFsCache)
require.Equal(t, uint64(1), metrics.ElementsMemoryCache)
t.Log(metrics.SizeMemoryCache)
require.InEpsilon(t, 2832576, metrics.SizeMemoryCache, 0.25)
require.InEpsilon(t, 3700000, metrics.SizeMemoryCache, 0.25)

// Instantiate 2
msg2 := []byte(`{"verifier": "fred", "beneficiary": "susi"}`)
Expand All @@ -301,7 +301,7 @@ func TestGetMetrics(t *testing.T) {
require.Equal(t, uint32(1), metrics.HitsMemoryCache)
require.Equal(t, uint32(1), metrics.HitsFsCache)
require.Equal(t, uint64(1), metrics.ElementsMemoryCache)
require.InEpsilon(t, 2832576, metrics.SizeMemoryCache, 0.25)
require.InEpsilon(t, 3700000, metrics.SizeMemoryCache, 0.25)

// Pin
err = vm.Pin(checksum)
Expand All @@ -314,8 +314,8 @@ func TestGetMetrics(t *testing.T) {
require.Equal(t, uint32(2), metrics.HitsFsCache)
require.Equal(t, uint64(1), metrics.ElementsPinnedMemoryCache)
require.Equal(t, uint64(1), metrics.ElementsMemoryCache)
require.InEpsilon(t, 2832576, metrics.SizePinnedMemoryCache, 0.25)
require.InEpsilon(t, 2832576, metrics.SizeMemoryCache, 0.25)
require.InEpsilon(t, 3700000, metrics.SizePinnedMemoryCache, 0.25)
require.InEpsilon(t, 3700000, metrics.SizeMemoryCache, 0.25)

// Instantiate 3
msg3 := []byte(`{"verifier": "fred", "beneficiary": "bert"}`)
Expand All @@ -333,8 +333,8 @@ func TestGetMetrics(t *testing.T) {
require.Equal(t, uint32(2), metrics.HitsFsCache)
require.Equal(t, uint64(1), metrics.ElementsPinnedMemoryCache)
require.Equal(t, uint64(1), metrics.ElementsMemoryCache)
require.InEpsilon(t, 2832576, metrics.SizePinnedMemoryCache, 0.25)
require.InEpsilon(t, 2832576, metrics.SizeMemoryCache, 0.25)
require.InEpsilon(t, 3700000, metrics.SizePinnedMemoryCache, 0.25)
require.InEpsilon(t, 3700000, metrics.SizeMemoryCache, 0.25)

// Unpin
err = vm.Unpin(checksum)
Expand All @@ -349,7 +349,7 @@ func TestGetMetrics(t *testing.T) {
require.Equal(t, uint64(0), metrics.ElementsPinnedMemoryCache)
require.Equal(t, uint64(1), metrics.ElementsMemoryCache)
require.Equal(t, uint64(0), metrics.SizePinnedMemoryCache)
require.InEpsilon(t, 2832576, metrics.SizeMemoryCache, 0.25)
require.InEpsilon(t, 3700000, metrics.SizeMemoryCache, 0.25)

// Instantiate 4
msg4 := []byte(`{"verifier": "fred", "beneficiary": "jeff"}`)
Expand All @@ -368,7 +368,7 @@ func TestGetMetrics(t *testing.T) {
require.Equal(t, uint64(0), metrics.ElementsPinnedMemoryCache)
require.Equal(t, uint64(1), metrics.ElementsMemoryCache)
require.Equal(t, uint64(0), metrics.SizePinnedMemoryCache)
require.InEpsilon(t, 2832576, metrics.SizeMemoryCache, 0.25)
require.InEpsilon(t, 3700000, metrics.SizeMemoryCache, 0.25)
}

func TestLongPayloadDeserialization(t *testing.T) {
Expand Down
Loading
Loading