diff --git a/.gitmodules b/.gitmodules index fea7abff6d..f44b7b2081 100644 --- a/.gitmodules +++ b/.gitmodules @@ -9,8 +9,8 @@ url = https://github.com/google/brotli.git [submodule "contracts"] path = contracts - url = https://github.com/VannaLabs/nitro-contracts.git - branch = develop + url = https://github.com/adambalogh/nitro-contracts.git + branch = main [submodule "arbitrator/wasm-testsuite/testsuite"] path = arbitrator/wasm-testsuite/testsuite url = https://github.com/WebAssembly/testsuite.git diff --git a/contracts b/contracts index 6125e9874b..b79b69eccb 160000 --- a/contracts +++ b/contracts @@ -1 +1 @@ -Subproject commit 6125e9874b4a91bdd8e7b4bcfcda237a81d18645 +Subproject commit b79b69eccb156c12de8f1d92b252395d2a5788ad diff --git a/go.mod b/go.mod index 5c3970ee17..29a4649625 100644 --- a/go.mod +++ b/go.mod @@ -268,6 +268,7 @@ require ( golang.org/x/exp v0.0.0-20230321023759-10a507213a29 // indirect golang.org/x/mod v0.10.0 // indirect golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect + gonum.org/v1/gonum v0.14.0 // indirect google.golang.org/genproto v0.0.0-20231016165738-49dd2c1f3d0b // indirect google.golang.org/genproto/googleapis/api v0.0.0-20231012201019-e917dd12ba7a // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20231030173426-d783a09b4405 // indirect diff --git a/go.sum b/go.sum index 424e3508c3..8d12fe6324 100644 --- a/go.sum +++ b/go.sum @@ -2077,6 +2077,8 @@ golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 h1:H2TDz8ibqkAF6YGhCdN3jS9O0/s90v0rJh3X/OLHEUk= golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= +gonum.org/v1/gonum v0.14.0 h1:2NiG67LD1tEH0D7kM+ps2V+fXmsAnpUeec7n8tcr4S0= +gonum.org/v1/gonum v0.14.0/go.mod h1:AoWeoz0becf9QMWtE8iWXNXc27fK4fNeHNf/oMejGfU= google.golang.org/api v0.0.0-20180910000450-7ca32eb868bf/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= google.golang.org/api v0.0.0-20181030000543-1d582fd0359e/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= google.golang.org/api v0.1.0/go.mod h1:UGEZY7KEX120AnNLIHFMKIo4obdJhkp2tPbaPlQx13Y= diff --git a/precompiles/ArbMathStats.go b/precompiles/ArbMathStats.go new file mode 100644 index 0000000000..572d828f2e --- /dev/null +++ b/precompiles/ArbMathStats.go @@ -0,0 +1,28 @@ +package precompiles + +import ( + "math" + "math/big" + + "gonum.org/v1/gonum/stat" +) + +// ArbMathStats provides methods for computing statistics +type ArbMathStats struct { + Address addr // 0x11b +} + +func (con *ArbMathStats) StdDev(c ctx, input []int32, decimals uint8) (huge, error) { + floatInput := make([]float64, len(input)) + for i, num := range input { + floatInput[i] = float64(num) + } + + stdev := big.NewFloat(stat.StdDev(floatInput, nil)) + stdev.Mul(stdev, big.NewFloat(math.Pow10(int(decimals)))) + + truncatedStdev := new(big.Int) + stdev.Int(truncatedStdev) + + return truncatedStdev, nil +} diff --git a/precompiles/ArbMathStats_test.go b/precompiles/ArbMathStats_test.go new file mode 100644 index 0000000000..0a04fc3b24 --- /dev/null +++ b/precompiles/ArbMathStats_test.go @@ -0,0 +1,35 @@ +package precompiles + +import ( + "math/big" + "testing" +) + +func TestArbMathStatsStandardDeviationIdenticalElements(t *testing.T) { + mathStats := ArbMathStats{} + + data := []int32{1, 1, 1, 1, 1, 1} + stdev, _ := mathStats.StdDev(nil, data, 0) + + if stdev.Cmp(big.NewInt(0)) != 0 { + t.Errorf("Expected stdev of 0 for identical elements, got: %s", stdev) + } +} + +func TestArbMathStatsStandardDeviation(t *testing.T) { + mathStats := ArbMathStats{} + + data := []int32{1, 5, 10, 100} + + stdev, _ := mathStats.StdDev(nil, data, 4) + expected := big.NewInt(474763) + if stdev.Cmp(expected) != 0 { + t.Errorf("Incorrect stddev, expected %s, got %s", expected, stdev) + } + + stdev, _ = mathStats.StdDev(nil, data, 2) + expected = big.NewInt(4747) + if stdev.Cmp(expected) != 0 { + t.Errorf("Incorrect stddev, expected %s, got %s", expected, stdev) + } +} diff --git a/precompiles/precompile.go b/precompiles/precompile.go index 031dbd6e21..3419c14719 100644 --- a/precompiles/precompile.go +++ b/precompiles/precompile.go @@ -541,6 +541,7 @@ func Precompiles() map[addr]ArbosPrecompile { insert(MakePrecompile(templates.ArbAggregatorMetaData, &ArbAggregator{Address: hex("6d")})) insert(MakePrecompile(templates.ArbStatisticsMetaData, &ArbStatistics{Address: hex("6f")})) insert(MakePrecompile(templates.ArbInferenceMetaData, &ArbInference{Address: hex("11a")})) + insert(MakePrecompile(templates.ArbMathStatsMetaData, &ArbMathStats{Address: hex("11b")})) eventCtx := func(gasLimit uint64, err error) *Context { if err != nil {