Skip to content
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
119 changes: 76 additions & 43 deletions internal/service/crypto_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ import (
"strings"
"testing"

sigparser "github.com/defiweb/go-sigparser"
"github.com/defiweb/go-sigparser"
"github.com/ethereum/go-ethereum/common"
hexutil "github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/gin-gonic/gin"
shs "github.com/shutter-network/rolling-shutter/rolling-shutter/keyperimpl/shutterservice"
shcommon "github.com/shutter-network/shutter-api/common"
Expand Down Expand Up @@ -54,50 +54,83 @@ func TestEventDecryptionValidation(t *testing.T) {

func TestEventDecryptionData(t *testing.T) {
router := setupRouter()
bites := `{"contract": "0x4d6dd1382aa09be1d243f8960409a1ab3d913f43", "eventSig":"event Transfer(address indexed from, address indexed to, uint256 amount)","arguments": [{"name": "from", "op": "eq", "bytes": "0x9e13976721ebff885611c8391d9b02749c1283fa"},{"name": "amount", "op": "gte", "number": "1"}]}`
w := httptest.NewRecorder()
fromAsBytes, err := hexutil.Decode("0x9e13976721ebff885611c8391d9b02749c1283fa")
assert.NilError(t, err, "hex decode failed")
var req usecase.EventTriggerDefinitionRequest
err = json.NewDecoder(strings.NewReader(bites)).Decode(&req)
assert.NilError(t, err, "invalid json")
sig, err := sigparser.ParseSignature(req.EventSignature)
g := shs.EventTriggerDefinition{
Contract: common.HexToAddress("0x4D6dD1382AA09be1d243F8960409A1ab3d913F43"),
LogPredicates: []shs.LogPredicate{
usecase.Topic0(sig),
{
LogValueRef: shs.LogValueRef{
Offset: 1,
Length: 1,
},
ValuePredicate: shs.ValuePredicate{
Op: shs.BytesEq,
ByteArgs: [][]byte{usecase.Align(fromAsBytes)},
},
},
{
LogValueRef: shs.LogValueRef{
Offset: 4,
Length: 1,

assertTriggerDefinitionEquals := func(t *testing.T, body string, expected shs.EventTriggerDefinition) {
t.Helper()

etd := usecase.EventTriggerDefinitionResponse{
EventTriggerDefinition: shcommon.PrefixWith0x(hex.EncodeToString(expected.MarshalBytes())),
}
expectedJSON, err := json.Marshal(etd)
assert.NilError(t, err, "error marshalling")

w := httptest.NewRecorder()
request, _ := http.NewRequest("POST", "/test", strings.NewReader(body))
router.ServeHTTP(w, request)

assert.Equal(t, 200, w.Code)
require.JSONEq(t, string(expectedJSON), w.Body.String(), "roundtrip failed")
}

t.Run("indexed from + amount", func(t *testing.T) {

body := `{"contract": "0x4d6dd1382aa09be1d243f8960409a1ab3d913f43", "eventSig":"event Transfer(address indexed from, address indexed to, uint256 amount)","arguments": [{"name": "from", "op": "eq", "bytes": "0x9e13976721ebff885611c8391d9b02749c1283fa"},{"name": "amount", "op": "gte", "number": "1"}]}`
fromAsBytes, err := hexutil.Decode("0x9e13976721ebff885611c8391d9b02749c1283fa")
assert.NilError(t, err, "hex decode failed")
var req usecase.EventTriggerDefinitionRequest
err = json.NewDecoder(strings.NewReader(body)).Decode(&req)
assert.NilError(t, err, "invalid json")
sig, err := sigparser.ParseSignature(req.EventSignature)
expected := shs.EventTriggerDefinition{
Contract: common.HexToAddress("0x4D6dD1382AA09be1d243F8960409A1ab3d913F43"),
LogPredicates: []shs.LogPredicate{
usecase.Topic0(sig),
{
LogValueRef: shs.LogValueRef{Offset: 1, Length: 1},
ValuePredicate: shs.ValuePredicate{
Op: shs.BytesEq,
ByteArgs: [][]byte{usecase.Align(fromAsBytes)},
},
},
ValuePredicate: shs.ValuePredicate{
Op: shs.UintGte,
IntArgs: []*big.Int{big.NewInt(1)},
{
LogValueRef: shs.LogValueRef{Offset: 4, Length: 1},
ValuePredicate: shs.ValuePredicate{
Op: shs.UintGte,
IntArgs: []*big.Int{big.NewInt(1)},
},
},
},
},
}
}

etd := usecase.EventTriggerDefinitionResponse{
EventTriggerDefinition: shcommon.PrefixWith0x(hex.EncodeToString(g.MarshalBytes())),
}
expected, err := json.Marshal(etd)
assert.NilError(t, err, "error marshalling")
assertTriggerDefinitionEquals(t, body, expected)
})

request, _ := http.NewRequest("POST", "/test", strings.NewReader(bites))
router.ServeHTTP(w, request)
t.Run("indexed to uses offset 2", func(t *testing.T) {
body := `{"contract": "0x4d6dd1382aa09be1d243f8960409a1ab3d913f43", "eventSig":"event Transfer(address indexed from, address indexed to, uint256 value)","arguments": [{"name": "to", "op": "eq", "bytes":"0x7e5f4552091a69125d5dfcb7b8c2659029395bdf"}]}`
toAsBytes, err := hexutil.Decode("0x7e5f4552091a69125d5dfcb7b8c2659029395bdf")
assert.NilError(t, err, "hex decode failed")
var req usecase.EventTriggerDefinitionRequest
err = json.NewDecoder(strings.NewReader(body)).Decode(&req)
assert.NilError(t, err, "invalid json")
sig, err := sigparser.ParseSignature(req.EventSignature)
assert.NilError(t, err, "invalid signature")
expected := shs.EventTriggerDefinition{
Contract: common.HexToAddress("0x4d6dd1382aa09be1d243f8960409a1ab3d913f43"),
LogPredicates: []shs.LogPredicate{
usecase.Topic0(sig),
{
LogValueRef: shs.LogValueRef{
Offset: 2,
Length: 1,
},
ValuePredicate: shs.ValuePredicate{
Op: shs.BytesEq,
ByteArgs: [][]byte{usecase.Align(toAsBytes)},
},
},
},
}

assert.Equal(t, 200, w.Code)
require.JSONEq(t, string(expected), w.Body.String(), "roundtrip failed")
}
assertTriggerDefinitionEquals(t, body, expected)
})
}
20 changes: 16 additions & 4 deletions internal/usecase/eventtrigger.go
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,19 @@ func Topic0(sig sigparser.Signature) shs.LogPredicate {
return lp
}

// indexedOffsetsForInputs returns topic offsets for indexed inputs in ABI order.
func indexedOffsetsForInputs(inputs []sigparser.Parameter) []uint64 {
indexedOffsets := make([]uint64, len(inputs))
indexedCount := uint64(0)
for i, input := range inputs {
if input.Indexed {
indexedOffsets[i] = 1 + indexedCount
indexedCount++
}
}
return indexedOffsets
}

func logPredicates(args []EventArgument, evtSig string) ([]shs.LogPredicate, error) {
lps := []shs.LogPredicate{}
sig, err := sigparser.ParseSignature(evtSig)
Expand All @@ -135,7 +148,7 @@ func logPredicates(args []EventArgument, evtSig string) ([]shs.LogPredicate, err
}
lp := Topic0(sig)
lps = append(lps, lp)
indexedOffset := uint64(1)
indexedOffsets := indexedOffsetsForInputs(sig.Inputs)
nonIndexedOffset := uint64(4)
length := uint64(0)
argnames := make([]string, len(args))
Expand All @@ -158,7 +171,7 @@ func logPredicates(args []EventArgument, evtSig string) ([]shs.LogPredicate, err
}
argnames[i] = arg.Name
}
for _, input := range sig.Inputs {
for inputIndex, input := range sig.Inputs {
lp := shs.LogPredicate{}
i := slices.IndexFunc(
args,
Expand All @@ -180,8 +193,7 @@ func logPredicates(args []EventArgument, evtSig string) ([]shs.LogPredicate, err
}
lp.ValuePredicate.Op = shs.BytesEq
lp.ValuePredicate.ByteArgs = [][]byte{Align(val)}
lp.LogValueRef.Offset = indexedOffset
indexedOffset++
lp.LogValueRef.Offset = indexedOffsets[inputIndex]
// input is data argument:
} else {
if input.Type != "uint256" {
Expand Down