diff --git a/Makefile b/Makefile index 82f2c982a7..8a432ad6e8 100644 --- a/Makefile +++ b/Makefile @@ -11,7 +11,7 @@ TEST_ARG= BUILD_PKGS=./ ./tools/wasp-cli/ ./tools/cluster/wasp-cluster/ ./tools/snap-cli/ BUILD_CMD=go build -o . -tags $(BUILD_TAGS) -ldflags $(BUILD_LD_FLAGS) -INSTALL_CMD=go install -tags $(BUILD_TAGS) -ldflags $(BUILD_LD_FLAGS) +INSTALL_CMD=go install -tags $(BUILD_TAGS) -ldflags $(BUILD_LD_FLAGS) all: build-lint @@ -64,5 +64,9 @@ docker-build: --build-arg BUILD_LD_FLAGS='${BUILD_LD_FLAGS}' \ . -.PHONY: all build build-lint test test-short test-full install lint gofumpt-list docker-build +deps-versions: + @grep -n "====" packages/testutil/privtangle/privtangle.go | \ + awk -F ":" '{ print $$1 }' | \ + { read from ; read to; awk -v s="$$from" -v e="$$to" 'NR>1*s&&NR<1*e' packages/testutil/privtangle/privtangle.go; } +.PHONY: all build build-lint test test-short test-full install lint gofumpt-list docker-build deps-versions diff --git a/contracts/wasm/corecontracts/test/core_accounts_test.go b/contracts/wasm/corecontracts/test/core_accounts_test.go index 3f6cc7ec5b..0b2b90f197 100644 --- a/contracts/wasm/corecontracts/test/core_accounts_test.go +++ b/contracts/wasm/corecontracts/test/core_accounts_test.go @@ -8,6 +8,9 @@ import ( "math/big" "testing" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "github.com/iotaledger/hive.go/serializer/v2" iotago "github.com/iotaledger/iota.go/v3" "github.com/iotaledger/wasp/packages/isc" @@ -16,8 +19,6 @@ import ( "github.com/iotaledger/wasp/packages/wasmvm/wasmlib/go/wasmlib/coreaccounts" "github.com/iotaledger/wasp/packages/wasmvm/wasmlib/go/wasmlib/wasmtypes" "github.com/iotaledger/wasp/packages/wasmvm/wasmsolo" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" ) const ( diff --git a/contracts/wasm/corecontracts/test/core_blob_test.go b/contracts/wasm/corecontracts/test/core_blob_test.go index 0af0d38e85..07431dac34 100644 --- a/contracts/wasm/corecontracts/test/core_blob_test.go +++ b/contracts/wasm/corecontracts/test/core_blob_test.go @@ -6,10 +6,11 @@ package test import ( "testing" + "github.com/stretchr/testify/require" + "github.com/iotaledger/wasp/packages/wasmvm/wasmlib/go/wasmlib/coreblob" "github.com/iotaledger/wasp/packages/wasmvm/wasmlib/go/wasmlib/wasmtypes" "github.com/iotaledger/wasp/packages/wasmvm/wasmsolo" - "github.com/stretchr/testify/require" ) // this is the expected blob hash for key0/val0 key1/val1 diff --git a/contracts/wasm/corecontracts/test/core_blocklog_test.go b/contracts/wasm/corecontracts/test/core_blocklog_test.go index e9cb43b0af..5d18712a9a 100644 --- a/contracts/wasm/corecontracts/test/core_blocklog_test.go +++ b/contracts/wasm/corecontracts/test/core_blocklog_test.go @@ -6,12 +6,13 @@ package test import ( "testing" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "github.com/iotaledger/wasp/packages/vm/core/blocklog" "github.com/iotaledger/wasp/packages/wasmvm/wasmlib/go/wasmlib/coreblocklog" "github.com/iotaledger/wasp/packages/wasmvm/wasmlib/go/wasmlib/wasmtypes" "github.com/iotaledger/wasp/packages/wasmvm/wasmsolo" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" ) func setupBlockLog(t *testing.T) *wasmsolo.SoloContext { diff --git a/contracts/wasm/corecontracts/test/core_governance_test.go b/contracts/wasm/corecontracts/test/core_governance_test.go index bb4816ba84..05c085d3c6 100644 --- a/contracts/wasm/corecontracts/test/core_governance_test.go +++ b/contracts/wasm/corecontracts/test/core_governance_test.go @@ -6,14 +6,15 @@ package test import ( "testing" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + iotago "github.com/iotaledger/iota.go/v3" "github.com/iotaledger/wasp/packages/vm/core/governance" "github.com/iotaledger/wasp/packages/vm/gas" "github.com/iotaledger/wasp/packages/wasmvm/wasmlib/go/wasmlib/coregovernance" "github.com/iotaledger/wasp/packages/wasmvm/wasmlib/go/wasmlib/wasmtypes" "github.com/iotaledger/wasp/packages/wasmvm/wasmsolo" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" ) func setupGovernance(t *testing.T) *wasmsolo.SoloContext { diff --git a/contracts/wasm/corecontracts/test/core_root_test.go b/contracts/wasm/corecontracts/test/core_root_test.go index 7fd9004bf9..fbe13872c1 100644 --- a/contracts/wasm/corecontracts/test/core_root_test.go +++ b/contracts/wasm/corecontracts/test/core_root_test.go @@ -7,11 +7,12 @@ import ( "os" "testing" + "github.com/stretchr/testify/require" + "github.com/iotaledger/wasp/packages/vm/core/root" "github.com/iotaledger/wasp/packages/wasmvm/wasmlib/go/wasmlib/coreblob" "github.com/iotaledger/wasp/packages/wasmvm/wasmlib/go/wasmlib/coreroot" "github.com/iotaledger/wasp/packages/wasmvm/wasmsolo" - "github.com/stretchr/testify/require" ) func setupRoot(t *testing.T) *wasmsolo.SoloContext { diff --git a/contracts/wasm/corecontracts/test/corecontracts_test.go b/contracts/wasm/corecontracts/test/corecontracts_test.go index 793169c116..a6e5f14f9c 100644 --- a/contracts/wasm/corecontracts/test/corecontracts_test.go +++ b/contracts/wasm/corecontracts/test/corecontracts_test.go @@ -6,9 +6,10 @@ package test import ( "testing" + "github.com/stretchr/testify/require" + "github.com/iotaledger/wasp/contracts/wasm/corecontracts/go/corecontracts" "github.com/iotaledger/wasp/packages/wasmvm/wasmsolo" - "github.com/stretchr/testify/require" ) func setup(t *testing.T) *wasmsolo.SoloContext { diff --git a/contracts/wasm/dividend/test/dividend_test.go b/contracts/wasm/dividend/test/dividend_test.go index aef88b3792..a87425ff64 100644 --- a/contracts/wasm/dividend/test/dividend_test.go +++ b/contracts/wasm/dividend/test/dividend_test.go @@ -6,10 +6,11 @@ package test import ( "testing" + "github.com/stretchr/testify/require" + "github.com/iotaledger/wasp/contracts/wasm/dividend/go/dividend" "github.com/iotaledger/wasp/packages/isc" "github.com/iotaledger/wasp/packages/wasmvm/wasmsolo" - "github.com/stretchr/testify/require" ) func dividendMember(ctx *wasmsolo.SoloContext, agent *wasmsolo.SoloAgent, factor uint64) { diff --git a/contracts/wasm/donatewithfeedback/test/donatewithfeedback_test.go b/contracts/wasm/donatewithfeedback/test/donatewithfeedback_test.go index 9b794f4cd4..75cf6a5dee 100644 --- a/contracts/wasm/donatewithfeedback/test/donatewithfeedback_test.go +++ b/contracts/wasm/donatewithfeedback/test/donatewithfeedback_test.go @@ -6,10 +6,11 @@ package test import ( "testing" + "github.com/stretchr/testify/require" + "github.com/iotaledger/wasp/contracts/wasm/donatewithfeedback/go/donatewithfeedback" "github.com/iotaledger/wasp/packages/isc" "github.com/iotaledger/wasp/packages/wasmvm/wasmsolo" - "github.com/stretchr/testify/require" ) func setupTest(t *testing.T) *wasmsolo.SoloContext { diff --git a/contracts/wasm/erc20/test/erc20_test.go b/contracts/wasm/erc20/test/erc20_test.go index 7708904f6d..4fe74a936f 100644 --- a/contracts/wasm/erc20/test/erc20_test.go +++ b/contracts/wasm/erc20/test/erc20_test.go @@ -3,12 +3,13 @@ package test import ( "testing" + "github.com/stretchr/testify/require" + "github.com/iotaledger/wasp/contracts/wasm/erc20/go/erc20" "github.com/iotaledger/wasp/packages/solo" "github.com/iotaledger/wasp/packages/utxodb" "github.com/iotaledger/wasp/packages/vm/core/corecontracts" "github.com/iotaledger/wasp/packages/wasmvm/wasmsolo" - "github.com/stretchr/testify/require" ) var ( diff --git a/contracts/wasm/erc20/test/init_test.go b/contracts/wasm/erc20/test/init_test.go index c20edeea7a..13c0c8dc9a 100644 --- a/contracts/wasm/erc20/test/init_test.go +++ b/contracts/wasm/erc20/test/init_test.go @@ -3,11 +3,12 @@ package test import ( "testing" + "github.com/stretchr/testify/require" + "github.com/iotaledger/wasp/contracts/wasm/erc20/go/erc20" "github.com/iotaledger/wasp/packages/utxodb" "github.com/iotaledger/wasp/packages/vm/core/corecontracts" "github.com/iotaledger/wasp/packages/wasmvm/wasmsolo" - "github.com/stretchr/testify/require" ) func TestDeployErc20(t *testing.T) { diff --git a/contracts/wasm/erc721/test/erc721_test.go b/contracts/wasm/erc721/test/erc721_test.go index 9bdbe14232..8d7812d303 100644 --- a/contracts/wasm/erc721/test/erc721_test.go +++ b/contracts/wasm/erc721/test/erc721_test.go @@ -6,10 +6,11 @@ package test import ( "testing" + "github.com/stretchr/testify/require" + "github.com/iotaledger/wasp/contracts/wasm/erc721/go/erc721" "github.com/iotaledger/wasp/packages/wasmvm/wasmlib/go/wasmlib/wasmtypes" "github.com/iotaledger/wasp/packages/wasmvm/wasmsolo" - "github.com/stretchr/testify/require" ) func TestDeploy(t *testing.T) { diff --git a/contracts/wasm/fairauction/test/fairauction_test.go b/contracts/wasm/fairauction/test/fairauction_test.go index 38f1596f4c..b7a7be001f 100644 --- a/contracts/wasm/fairauction/test/fairauction_test.go +++ b/contracts/wasm/fairauction/test/fairauction_test.go @@ -7,11 +7,12 @@ import ( "testing" "time" + "github.com/stretchr/testify/require" + "github.com/iotaledger/wasp/contracts/wasm/fairauction/go/fairauction" "github.com/iotaledger/wasp/packages/wasmvm/wasmlib/go/wasmlib" "github.com/iotaledger/wasp/packages/wasmvm/wasmlib/go/wasmlib/wasmtypes" "github.com/iotaledger/wasp/packages/wasmvm/wasmsolo" - "github.com/stretchr/testify/require" ) const ( diff --git a/contracts/wasm/fairroulette/test/fairroulette_test.go b/contracts/wasm/fairroulette/test/fairroulette_test.go index 7361f6f09f..694f0d8cd5 100644 --- a/contracts/wasm/fairroulette/test/fairroulette_test.go +++ b/contracts/wasm/fairroulette/test/fairroulette_test.go @@ -7,9 +7,10 @@ import ( "testing" "time" + "github.com/stretchr/testify/require" + "github.com/iotaledger/wasp/contracts/wasm/fairroulette/go/fairroulette" "github.com/iotaledger/wasp/packages/wasmvm/wasmsolo" - "github.com/stretchr/testify/require" ) func setupTest(t *testing.T) *wasmsolo.SoloContext { diff --git a/contracts/wasm/gascalibration/executiontime/test/executiontime_test.go b/contracts/wasm/gascalibration/executiontime/test/executiontime_test.go index 78e1d20117..9f0f8ca1f6 100644 --- a/contracts/wasm/gascalibration/executiontime/test/executiontime_test.go +++ b/contracts/wasm/gascalibration/executiontime/test/executiontime_test.go @@ -7,11 +7,12 @@ import ( "flag" "testing" + "github.com/stretchr/testify/require" + "github.com/iotaledger/wasp/contracts/wasm/gascalibration" "github.com/iotaledger/wasp/contracts/wasm/gascalibration/executiontime/go/executiontime" "github.com/iotaledger/wasp/packages/wasmvm/wasmlib/go/wasmlib" "github.com/iotaledger/wasp/packages/wasmvm/wasmsolo" - "github.com/stretchr/testify/require" ) var force = flag.Bool("force", false, "") diff --git a/contracts/wasm/gascalibration/memory/test/memory_test.go b/contracts/wasm/gascalibration/memory/test/memory_test.go index f59f67f278..28c7afaf4b 100644 --- a/contracts/wasm/gascalibration/memory/test/memory_test.go +++ b/contracts/wasm/gascalibration/memory/test/memory_test.go @@ -7,11 +7,12 @@ import ( "flag" "testing" + "github.com/stretchr/testify/require" + "github.com/iotaledger/wasp/contracts/wasm/gascalibration" "github.com/iotaledger/wasp/contracts/wasm/gascalibration/memory/go/memory" "github.com/iotaledger/wasp/packages/wasmvm/wasmlib/go/wasmlib" "github.com/iotaledger/wasp/packages/wasmvm/wasmsolo" - "github.com/stretchr/testify/require" ) var force = flag.Bool("force", false, "") diff --git a/contracts/wasm/gascalibration/storage/test/storage_test.go b/contracts/wasm/gascalibration/storage/test/storage_test.go index 02a5f7cb9f..63d017e726 100644 --- a/contracts/wasm/gascalibration/storage/test/storage_test.go +++ b/contracts/wasm/gascalibration/storage/test/storage_test.go @@ -7,11 +7,12 @@ import ( "flag" "testing" + "github.com/stretchr/testify/require" + "github.com/iotaledger/wasp/contracts/wasm/gascalibration" "github.com/iotaledger/wasp/contracts/wasm/gascalibration/storage/go/storage" "github.com/iotaledger/wasp/packages/wasmvm/wasmlib/go/wasmlib" "github.com/iotaledger/wasp/packages/wasmvm/wasmsolo" - "github.com/stretchr/testify/require" ) var force = flag.Bool("force", false, "") diff --git a/contracts/wasm/helloworld/test/helloworld_test.go b/contracts/wasm/helloworld/test/helloworld_test.go index a027332cfb..0310e5e184 100644 --- a/contracts/wasm/helloworld/test/helloworld_test.go +++ b/contracts/wasm/helloworld/test/helloworld_test.go @@ -6,9 +6,10 @@ package test import ( "testing" + "github.com/stretchr/testify/require" + "github.com/iotaledger/wasp/contracts/wasm/helloworld/go/helloworld" "github.com/iotaledger/wasp/packages/wasmvm/wasmsolo" - "github.com/stretchr/testify/require" ) func setupTest(t *testing.T) *wasmsolo.SoloContext { diff --git a/contracts/wasm/inccounter/test/inccounter_test.go b/contracts/wasm/inccounter/test/inccounter_test.go index 16d0e2a5f0..5b81249195 100644 --- a/contracts/wasm/inccounter/test/inccounter_test.go +++ b/contracts/wasm/inccounter/test/inccounter_test.go @@ -8,10 +8,11 @@ import ( "testing" "time" + "github.com/stretchr/testify/require" + "github.com/iotaledger/wasp/contracts/wasm/inccounter/go/inccounter" "github.com/iotaledger/wasp/packages/wasmvm/wasmhost" "github.com/iotaledger/wasp/packages/wasmvm/wasmsolo" - "github.com/stretchr/testify/require" ) func setupTest(t *testing.T) *wasmsolo.SoloContext { diff --git a/contracts/wasm/schemacomment/test/schemacomment_test.go b/contracts/wasm/schemacomment/test/schemacomment_test.go index b175572392..e055bd2ab1 100644 --- a/contracts/wasm/schemacomment/test/schemacomment_test.go +++ b/contracts/wasm/schemacomment/test/schemacomment_test.go @@ -6,9 +6,10 @@ package test import ( "testing" + "github.com/stretchr/testify/require" + "github.com/iotaledger/wasp/contracts/wasm/schemacomment/go/schemacomment" "github.com/iotaledger/wasp/packages/wasmvm/wasmsolo" - "github.com/stretchr/testify/require" ) func TestDeploy(t *testing.T) { diff --git a/contracts/wasm/testcore/test/call_test.go b/contracts/wasm/testcore/test/call_test.go index b66785cd45..4f5e699fae 100644 --- a/contracts/wasm/testcore/test/call_test.go +++ b/contracts/wasm/testcore/test/call_test.go @@ -3,9 +3,10 @@ package test import ( "testing" + "github.com/stretchr/testify/require" + "github.com/iotaledger/wasp/contracts/wasm/testcore/go/testcore" "github.com/iotaledger/wasp/packages/wasmvm/wasmlib/go/wasmlib/wasmtypes" - "github.com/stretchr/testify/require" ) // N Fib(N) Calls diff --git a/contracts/wasm/testcore/test/check_ctx_test.go b/contracts/wasm/testcore/test/check_ctx_test.go index ce20d25d49..98be76b8a0 100644 --- a/contracts/wasm/testcore/test/check_ctx_test.go +++ b/contracts/wasm/testcore/test/check_ctx_test.go @@ -3,8 +3,9 @@ package test import ( "testing" - "github.com/iotaledger/wasp/contracts/wasm/testcore/go/testcore" "github.com/stretchr/testify/require" + + "github.com/iotaledger/wasp/contracts/wasm/testcore/go/testcore" ) func TestMainCallsFromFullEP(t *testing.T) { diff --git a/contracts/wasm/testcore/test/concurrency_test.go b/contracts/wasm/testcore/test/concurrency_test.go index 05549f5c61..c919798707 100644 --- a/contracts/wasm/testcore/test/concurrency_test.go +++ b/contracts/wasm/testcore/test/concurrency_test.go @@ -5,12 +5,13 @@ import ( "testing" "time" + "github.com/stretchr/testify/require" + "github.com/iotaledger/wasp/contracts/wasm/testcore/go/testcore" "github.com/iotaledger/wasp/packages/kv/codec" "github.com/iotaledger/wasp/packages/solo" "github.com/iotaledger/wasp/packages/utxodb" "github.com/iotaledger/wasp/packages/wasmvm/wasmsolo" - "github.com/stretchr/testify/require" ) func TestCounter(t *testing.T) { diff --git a/contracts/wasm/testcore/test/init_fail_test.go b/contracts/wasm/testcore/test/init_fail_test.go index 80ca104644..cfc83300eb 100644 --- a/contracts/wasm/testcore/test/init_fail_test.go +++ b/contracts/wasm/testcore/test/init_fail_test.go @@ -3,10 +3,11 @@ package test import ( "testing" + "github.com/stretchr/testify/require" + "github.com/iotaledger/wasp/contracts/wasm/testcore/go/testcore" "github.com/iotaledger/wasp/packages/vm/core/corecontracts" "github.com/iotaledger/wasp/packages/wasmvm/wasmsolo" - "github.com/stretchr/testify/require" ) func TestInitSuccess(t *testing.T) { diff --git a/contracts/wasm/testcore/test/misc_call_test.go b/contracts/wasm/testcore/test/misc_call_test.go index 9554c3b355..127344b442 100644 --- a/contracts/wasm/testcore/test/misc_call_test.go +++ b/contracts/wasm/testcore/test/misc_call_test.go @@ -3,8 +3,9 @@ package test import ( "testing" - "github.com/iotaledger/wasp/contracts/wasm/testcore/go/testcore" "github.com/stretchr/testify/require" + + "github.com/iotaledger/wasp/contracts/wasm/testcore/go/testcore" ) func TestChainOwnerIDView(t *testing.T) { diff --git a/contracts/wasm/testcore/test/offledger_test.go b/contracts/wasm/testcore/test/offledger_test.go index f46f387812..29dc74e53b 100644 --- a/contracts/wasm/testcore/test/offledger_test.go +++ b/contracts/wasm/testcore/test/offledger_test.go @@ -3,10 +3,11 @@ package test import ( "testing" + "github.com/stretchr/testify/require" + "github.com/iotaledger/wasp/contracts/wasm/testcore/go/testcore" "github.com/iotaledger/wasp/packages/utxodb" "github.com/iotaledger/wasp/packages/wasmvm/wasmsolo" - "github.com/stretchr/testify/require" ) func TestOffLedgerFailNoAccount(t *testing.T) { diff --git a/contracts/wasm/testcore/test/sandbox_panic_test.go b/contracts/wasm/testcore/test/sandbox_panic_test.go index eae3aea37b..a615986bb6 100644 --- a/contracts/wasm/testcore/test/sandbox_panic_test.go +++ b/contracts/wasm/testcore/test/sandbox_panic_test.go @@ -4,10 +4,11 @@ import ( "strings" "testing" + "github.com/stretchr/testify/require" + "github.com/iotaledger/wasp/contracts/wasm/testcore/go/testcore" "github.com/iotaledger/wasp/packages/vm/core/testcore/sbtests/sbtestsc" "github.com/iotaledger/wasp/packages/wasmvm/wasmsolo" - "github.com/stretchr/testify/require" ) func verifyErrorInReceipts(t *testing.T, ctx *wasmsolo.SoloContext, msg string) { diff --git a/contracts/wasm/testcore/test/spawn_test.go b/contracts/wasm/testcore/test/spawn_test.go index b18eed8a82..b21b95544e 100644 --- a/contracts/wasm/testcore/test/spawn_test.go +++ b/contracts/wasm/testcore/test/spawn_test.go @@ -3,9 +3,10 @@ package test import ( "testing" + "github.com/stretchr/testify/require" + "github.com/iotaledger/wasp/contracts/wasm/testcore/go/testcore" "github.com/iotaledger/wasp/packages/vm/core/corecontracts" - "github.com/stretchr/testify/require" ) func TestSpawn(t *testing.T) { diff --git a/contracts/wasm/testcore/test/testcore_test.go b/contracts/wasm/testcore/test/testcore_test.go index 051445b4b2..8e62dc016b 100644 --- a/contracts/wasm/testcore/test/testcore_test.go +++ b/contracts/wasm/testcore/test/testcore_test.go @@ -4,6 +4,8 @@ import ( "fmt" "testing" + "github.com/stretchr/testify/require" + "github.com/iotaledger/wasp/contracts/wasm/testcore/go/testcore" "github.com/iotaledger/wasp/packages/solo" "github.com/iotaledger/wasp/packages/util" @@ -13,7 +15,6 @@ import ( "github.com/iotaledger/wasp/packages/wasmvm/wasmlib/go/wasmlib/coreaccounts" "github.com/iotaledger/wasp/packages/wasmvm/wasmlib/go/wasmlib/coreroot" "github.com/iotaledger/wasp/packages/wasmvm/wasmsolo" - "github.com/stretchr/testify/require" ) func deployTestCore(t *testing.T, runWasm bool, addCreator ...bool) *wasmsolo.SoloContext { diff --git a/contracts/wasm/testcore/test/transfer_test.go b/contracts/wasm/testcore/test/transfer_test.go index 484440499a..f5e5fc2ae5 100644 --- a/contracts/wasm/testcore/test/transfer_test.go +++ b/contracts/wasm/testcore/test/transfer_test.go @@ -3,10 +3,11 @@ package test import ( "testing" + "github.com/stretchr/testify/require" + "github.com/iotaledger/wasp/contracts/wasm/testcore/go/testcore" "github.com/iotaledger/wasp/packages/isc" "github.com/iotaledger/wasp/packages/solo" - "github.com/stretchr/testify/require" ) func TestDoNothing(t *testing.T) { diff --git a/contracts/wasm/testcore/test/types_test.go b/contracts/wasm/testcore/test/types_test.go index 04a4b3cab8..6cada0ef5b 100644 --- a/contracts/wasm/testcore/test/types_test.go +++ b/contracts/wasm/testcore/test/types_test.go @@ -3,10 +3,11 @@ package test import ( "testing" + "github.com/stretchr/testify/require" + "github.com/iotaledger/wasp/contracts/wasm/testcore/go/testcore" "github.com/iotaledger/wasp/packages/hashing" "github.com/iotaledger/wasp/packages/isc" - "github.com/stretchr/testify/require" ) //nolint:dupl diff --git a/contracts/wasm/testwasmlib/test/testwasmlib_bigint_test.go b/contracts/wasm/testwasmlib/test/testwasmlib_bigint_test.go index 4b21efaf3f..7291319381 100644 --- a/contracts/wasm/testwasmlib/test/testwasmlib_bigint_test.go +++ b/contracts/wasm/testwasmlib/test/testwasmlib_bigint_test.go @@ -7,10 +7,11 @@ import ( "math/rand" "testing" + "github.com/stretchr/testify/require" + "github.com/iotaledger/wasp/contracts/wasm/testwasmlib/go/testwasmlib" "github.com/iotaledger/wasp/packages/wasmvm/wasmlib/go/wasmlib/wasmtypes" "github.com/iotaledger/wasp/packages/wasmvm/wasmsolo" - "github.com/stretchr/testify/require" ) const ( diff --git a/contracts/wasm/testwasmlib/test/testwasmlib_client_test.go b/contracts/wasm/testwasmlib/test/testwasmlib_client_test.go index f5d29751f3..137bb11e28 100644 --- a/contracts/wasm/testwasmlib/test/testwasmlib_client_test.go +++ b/contracts/wasm/testwasmlib/test/testwasmlib_client_test.go @@ -6,6 +6,8 @@ import ( "testing" "time" + "github.com/stretchr/testify/require" + "github.com/iotaledger/wasp/client/chainclient" "github.com/iotaledger/wasp/contracts/wasm/testwasmlib/go/testwasmlib" "github.com/iotaledger/wasp/packages/cryptolib" @@ -13,7 +15,6 @@ import ( "github.com/iotaledger/wasp/packages/wasmvm/wasmlib/go/wasmlib/wasmtypes" "github.com/iotaledger/wasp/packages/wasmvm/wasmsolo" cluster_tests "github.com/iotaledger/wasp/tools/cluster/tests" - "github.com/stretchr/testify/require" ) const ( diff --git a/contracts/wasm/testwasmlib/test/testwasmlib_proxy_test.go b/contracts/wasm/testwasmlib/test/testwasmlib_proxy_test.go index f5651ed964..bb54e93cd3 100644 --- a/contracts/wasm/testwasmlib/test/testwasmlib_proxy_test.go +++ b/contracts/wasm/testwasmlib/test/testwasmlib_proxy_test.go @@ -6,11 +6,12 @@ package test import ( "testing" + "github.com/stretchr/testify/require" + "github.com/iotaledger/wasp/contracts/wasm/testwasmlib/go/testwasmlib" "github.com/iotaledger/wasp/packages/wasmvm/wasmhost" "github.com/iotaledger/wasp/packages/wasmvm/wasmlib/go/wasmlib/wasmtypes" "github.com/iotaledger/wasp/packages/wasmvm/wasmsolo" - "github.com/stretchr/testify/require" ) func TestStringMapOfStringArrayClear(t *testing.T) { diff --git a/contracts/wasm/testwasmlib/test/testwasmlib_test.go b/contracts/wasm/testwasmlib/test/testwasmlib_test.go index 8c02a6c8c4..f41b81313b 100644 --- a/contracts/wasm/testwasmlib/test/testwasmlib_test.go +++ b/contracts/wasm/testwasmlib/test/testwasmlib_test.go @@ -11,6 +11,8 @@ import ( "strings" "testing" + "github.com/stretchr/testify/require" + iotago "github.com/iotaledger/iota.go/v3" "github.com/iotaledger/wasp/contracts/wasm/testwasmlib/go/testwasmlib" "github.com/iotaledger/wasp/packages/hashing" @@ -20,7 +22,6 @@ import ( "github.com/iotaledger/wasp/packages/wasmvm/wasmlib/go/wasmlib/coreblocklog" "github.com/iotaledger/wasp/packages/wasmvm/wasmlib/go/wasmlib/wasmtypes" "github.com/iotaledger/wasp/packages/wasmvm/wasmsolo" - "github.com/stretchr/testify/require" ) var ( diff --git a/contracts/wasm/timestamp/test/timestamp_test.go b/contracts/wasm/timestamp/test/timestamp_test.go index 1eb2423fee..d3fdb9e554 100644 --- a/contracts/wasm/timestamp/test/timestamp_test.go +++ b/contracts/wasm/timestamp/test/timestamp_test.go @@ -3,9 +3,10 @@ package test import ( "testing" + "github.com/stretchr/testify/require" + "github.com/iotaledger/wasp/contracts/wasm/timestamp/go/timestamp" "github.com/iotaledger/wasp/packages/wasmvm/wasmsolo" - "github.com/stretchr/testify/require" ) func TestDeploy(t *testing.T) { diff --git a/contracts/wasm/tokenregistry/test/tokenregistry_test.go b/contracts/wasm/tokenregistry/test/tokenregistry_test.go index 1fe41d8298..e4bf69155b 100644 --- a/contracts/wasm/tokenregistry/test/tokenregistry_test.go +++ b/contracts/wasm/tokenregistry/test/tokenregistry_test.go @@ -6,9 +6,10 @@ package test import ( "testing" + "github.com/stretchr/testify/require" + "github.com/iotaledger/wasp/contracts/wasm/tokenregistry/go/tokenregistry" "github.com/iotaledger/wasp/packages/wasmvm/wasmsolo" - "github.com/stretchr/testify/require" ) func setupTest(t *testing.T) *wasmsolo.SoloContext { diff --git a/documentation/docs/configuration.md b/documentation/docs/configuration.md index 11395c7f5d..fdc60fdb4b 100755 --- a/documentation/docs/configuration.md +++ b/documentation/docs/configuration.md @@ -1,9 +1,6 @@ - --- +# !!! DO NOT MODIFY !!! +# This file is auto-generated by the gendoc tool based on the source code of the app. description: This section describes the configuration parameters and their types for WASP. keywords: - IOTA Node diff --git a/packages/authentication/jwt_handler.go b/packages/authentication/jwt_handler.go index 984339b0b0..ce976f04bf 100644 --- a/packages/authentication/jwt_handler.go +++ b/packages/authentication/jwt_handler.go @@ -15,6 +15,8 @@ import ( "github.com/iotaledger/wasp/packages/users" ) +const headerXForwardedPrefix = "X-Forwarded-Prefix" + type AuthHandler struct { Jwt *JWTAuth Users map[string]*users.UserData @@ -71,10 +73,14 @@ func (a *AuthHandler) handleJSONAuthRequest(c echo.Context, token string, errorR return c.JSON(http.StatusOK, shared.LoginResponse{JWT: token}) } +func (a *AuthHandler) redirect(c echo.Context, uri string) error { + return c.Redirect(http.StatusFound, c.Request().Header.Get(headerXForwardedPrefix)+uri) +} + func (a *AuthHandler) handleFormAuthRequest(c echo.Context, token string, errorResult error) error { if errorResult != nil { // TODO: Add sessions to get rid of the query parameter? - return c.Redirect(http.StatusFound, fmt.Sprintf("%s?error=%s", shared.AuthRoute(), errorResult)) + return a.redirect(c, fmt.Sprintf("%s?error=%s", shared.AuthRoute(), errorResult)) } cookie := http.Cookie{ @@ -88,7 +94,7 @@ func (a *AuthHandler) handleFormAuthRequest(c echo.Context, token string, errorR c.SetCookie(&cookie) - return c.Redirect(http.StatusFound, shared.AuthRouteSuccess()) + return a.redirect(c, shared.AuthRouteSuccess()) } func (a *AuthHandler) CrossAPIAuthHandler(c echo.Context) error { diff --git a/packages/chain/chain.go b/packages/chain/chain.go index 5dedb6de1c..dd9fbfd8e3 100644 --- a/packages/chain/chain.go +++ b/packages/chain/chain.go @@ -9,8 +9,8 @@ import ( "github.com/iotaledger/hive.go/core/events" "github.com/iotaledger/hive.go/core/kvstore" "github.com/iotaledger/hive.go/core/logger" + "github.com/iotaledger/inx-app/nodebridge" iotago "github.com/iotaledger/iota.go/v3" - "github.com/iotaledger/iota.go/v3/nodeclient" "github.com/iotaledger/trie.go/trie" "github.com/iotaledger/wasp/packages/chain/mempool" "github.com/iotaledger/wasp/packages/chain/messages" @@ -93,52 +93,26 @@ type Committee interface { GetRandomValidators(upToN int) []*cryptolib.PublicKey // TODO: Remove after OffLedgerRequest dissemination is changed. } -type ( - NodeConnectionAliasOutputHandlerFun func(*isc.AliasOutputWithID) - NodeConnectionOnLedgerRequestHandlerFun func(isc.OnLedgerRequest) - NodeConnectionInclusionStateHandlerFun func(iotago.TransactionID, string) - NodeConnectionMilestonesHandlerFun func(*nodeclient.MilestoneInfo) -) - type NodeConnection interface { - RegisterChain(chainID *isc.ChainID, stateOutputHandler, outputHandler func(iotago.OutputID, iotago.Output)) + RegisterChain( + chainID *isc.ChainID, + stateOutputHandler, + outputHandler func(iotago.OutputID, iotago.Output), + milestoneHandler func(*nodebridge.Milestone), + ) UnregisterChain(chainID *isc.ChainID) - PublishStateTransaction(chainID *isc.ChainID, stateIndex uint32, tx *iotago.Transaction) error - PublishGovernanceTransaction(chainID *isc.ChainID, tx *iotago.Transaction) error + PublishTransaction(chainID *isc.ChainID, tx *iotago.Transaction) error PullLatestOutput(chainID *isc.ChainID) - PullTxInclusionState(chainID *isc.ChainID, txid iotago.TransactionID) PullStateOutputByID(chainID *isc.ChainID, id *iotago.UTXOInput) - AttachTxInclusionStateEvents(chainID *isc.ChainID, handler NodeConnectionInclusionStateHandlerFun) (*events.Closure, error) - DetachTxInclusionStateEvents(chainID *isc.ChainID, closure *events.Closure) error - AttachMilestones(handler NodeConnectionMilestonesHandlerFun) *events.Closure + AttachMilestones(handler func(*nodebridge.Milestone)) *events.Closure DetachMilestones(attachID *events.Closure) SetMetrics(metrics nodeconnmetrics.NodeConnectionMetrics) GetMetrics() nodeconnmetrics.NodeConnectionMetrics } -type ChainNodeConnection interface { - AttachToAliasOutput(NodeConnectionAliasOutputHandlerFun) - DetachFromAliasOutput() - AttachToOnLedgerRequest(NodeConnectionOnLedgerRequestHandlerFun) - DetachFromOnLedgerRequest() - AttachToTxInclusionState(NodeConnectionInclusionStateHandlerFun) - DetachFromTxInclusionState() - AttachToMilestones(NodeConnectionMilestonesHandlerFun) - DetachFromMilestones() - Close() - - PublishStateTransaction(stateIndex uint32, tx *iotago.Transaction) error - PublishGovernanceTransaction(tx *iotago.Transaction) error - PullLatestOutput() - PullTxInclusionState(txid iotago.TransactionID) - PullStateOutputByID(*iotago.UTXOInput) - - GetMetrics() nodeconnmetrics.NodeConnectionMessagesMetrics -} - type StateManager interface { Ready() *ready.Ready EnqueueGetBlockMsg(msg *messages.GetBlockMsgIn) @@ -155,7 +129,6 @@ type Consensus interface { EnqueueStateTransitionMsg(bool, state.VirtualStateAccess, *isc.AliasOutputWithID, time.Time) EnqueueDssIndexProposalMsg(msg *messages.DssIndexProposalMsg) EnqueueDssSignatureMsg(msg *messages.DssSignatureMsg) - EnqueueTxInclusionsStateMsg(iotago.TransactionID, string) EnqueueAsynchronousCommonSubsetMsg(msg *messages.AsynchronousCommonSubsetMsg) EnqueueVMResultMsg(msg *messages.VMResultMsg) EnqueueTimerMsg(messages.TimerTick) @@ -165,6 +138,7 @@ type Consensus interface { GetWorkflowStatus() ConsensusWorkflowStatus ShouldReceiveMissingRequest(req isc.Request) bool GetPipeMetrics() ConsensusPipeMetrics + SetTimeData(time.Time) } type AsynchronousCommonSubsetRunner interface { @@ -219,7 +193,6 @@ type ConsensusWorkflowStatus interface { type ConsensusPipeMetrics interface { GetEventStateTransitionMsgPipeSize() int GetEventPeerLogIndexMsgPipeSize() int - GetEventInclusionStateMsgPipeSize() int GetEventACSMsgPipeSize() int GetEventVMResultMsgPipeSize() int GetEventTimerMsgPipeSize() int diff --git a/packages/chain/chainimpl/chainimpl.go b/packages/chain/chainimpl/chainimpl.go index de7347b433..ecd5e56741 100644 --- a/packages/chain/chainimpl/chainimpl.go +++ b/packages/chain/chainimpl/chainimpl.go @@ -17,7 +17,6 @@ import ( dss_node_pkg "github.com/iotaledger/wasp/packages/chain/dss/node" mempool_pkg "github.com/iotaledger/wasp/packages/chain/mempool" "github.com/iotaledger/wasp/packages/chain/messages" - "github.com/iotaledger/wasp/packages/chain/nodeconnchain" "github.com/iotaledger/wasp/packages/chain/statemgr" "github.com/iotaledger/wasp/packages/cryptolib" "github.com/iotaledger/wasp/packages/isc" @@ -38,11 +37,6 @@ import ( const maxMsgBuffer = 1000 -var ( - _ chain.Chain = &chainObj{} - _ map[cryptolib.PublicKeyKey]bool // We rely on value comparison on the pubkeys, just assert that here. -) - type chainObj struct { committee atomic.Value mempool mempool_pkg.Mempool @@ -58,7 +52,7 @@ type chainObj struct { consensus chain.Consensus dssNode dss_node_pkg.DSSNode log *logger.Logger - nodeConn chain.ChainNodeConnection + nodeConn chain.NodeConnection db kvstore.KVStore netProvider peering.NetworkProvider dksProvider registry.DKShareRegistryProvider @@ -150,11 +144,7 @@ func NewChain( consensusJournalRegistry: consensusJournalRegistry, wal: wal, dssNode: dss_node_pkg.New(&peeringID, netProvider, nodeIdentity, log), - } - ret.nodeConn, err = nodeconnchain.NewChainNodeConnection(chainID, nc, chainLog) - if err != nil { - ret.log.Errorf("NewChain: unable to create chain node connection: %v", err) - return nil + nodeConn: nc, } ret.committee.Store(&committeeStruct{}) @@ -176,8 +166,14 @@ func NewChain( ret.eventChainTransitionClosure = events.NewClosure(ret.processChainTransition) ret.eventChainTransition.Hook(ret.eventChainTransitionClosure) - ret.nodeConn.AttachToOnLedgerRequest(ret.receiveOnLedgerRequest) - ret.nodeConn.AttachToAliasOutput(ret.EnqueueAliasOutput) + + nc.RegisterChain( + chainID, + ret.stateOutputHandler, + ret.outputHandler, + ret.handleMilestone, + ) + ret.receiveChainPeerMessagesAttachID = ret.chainPeers.Attach(peering.PeerMessageReceiverChain, ret.receiveChainPeerMessages) go ret.recvLoop() ret.startTimer() @@ -196,11 +192,6 @@ func (c *chainObj) startTimer() { }() } -func (c *chainObj) receiveOnLedgerRequest(request isc.OnLedgerRequest) { - c.log.Debugf("receiveOnLedgerRequest: %s", request.ID()) - c.mempool.ReceiveRequest(request) -} - func (c *chainObj) receiveCommitteePeerMessages(peerMsg *peering.PeerMessageGroupIn) { if peerMsg.MsgType != chain.PeerMsgTypeMissingRequestIDs { c.log.Warnf("Wrong type of chain message (with committee peering ID): %v, ignoring it", peerMsg.MsgType) diff --git a/packages/chain/chainimpl/entry.go b/packages/chain/chainimpl/dismiss.go similarity index 92% rename from packages/chain/chainimpl/entry.go rename to packages/chain/chainimpl/dismiss.go index 8698a400a3..fb6fbc9746 100644 --- a/packages/chain/chainimpl/entry.go +++ b/packages/chain/chainimpl/dismiss.go @@ -14,10 +14,10 @@ func (c *chainObj) Dismiss(reason string) { c.dismissOnce.Do(func() { c.dismissed.Store(true) c.chainPeers.Detach(c.receiveChainPeerMessagesAttachID) - c.nodeConn.DetachFromOnLedgerRequest() - c.nodeConn.DetachFromAliasOutput() c.eventChainTransition.Detach(c.eventChainTransitionClosure) + c.nodeConn.UnregisterChain(c.chainID) + c.mempool.Close() c.stateMgr.Close() cmt := c.getCommittee() @@ -32,7 +32,6 @@ func (c *chainObj) Dismiss(reason string) { c.eventRequestProcessed.DetachAll() c.eventChainTransition.DetachAll() c.chainPeers.Close() - c.nodeConn.Close() c.dismissChainMsgPipe.Close() c.aliasOutputPipe.Close() diff --git a/packages/chain/chainimpl/eventproc.go b/packages/chain/chainimpl/eventproc.go index b9d937deac..c8b3723c46 100644 --- a/packages/chain/chainimpl/eventproc.go +++ b/packages/chain/chainimpl/eventproc.go @@ -247,7 +247,18 @@ func (c *chainObj) createNewCommitteeAndConsensus(dkShare tcrypto.DKShare) error if err != nil { return xerrors.Errorf("cannot load consensus journal: %w", err) } - c.consensus = consensus.New(c, c.mempool, cmt, cmtPeerGroup, c.nodeConn, c.pullMissingRequestsFromCommittee, c.chainMetrics, c.dssNode, consensusJournal, c.wal) + c.consensus = consensus.New( + c, + c.mempool, + cmt, + cmtPeerGroup, + c.pullMissingRequestsFromCommittee, + c.chainMetrics, + c.dssNode, + consensusJournal, + c.wal, + c.nodeConn.PublishTransaction, + ) c.setCommittee(cmt) return nil } diff --git a/packages/chain/chainimpl/l1handlers.go b/packages/chain/chainimpl/l1handlers.go new file mode 100644 index 0000000000..e5f3701202 --- /dev/null +++ b/packages/chain/chainimpl/l1handlers.go @@ -0,0 +1,79 @@ +package chainimpl + +import ( + "time" + + "github.com/iotaledger/inx-app/nodebridge" + iotago "github.com/iotaledger/iota.go/v3" + "github.com/iotaledger/wasp/packages/isc" + "github.com/iotaledger/wasp/packages/util" +) + +func (c *chainObj) handleMilestone(metadata *nodebridge.Milestone) { + c.log.Debugf("received milestone index : %d", metadata.Milestone.Index) + if c.consensus != nil { + c.consensus.SetTimeData(time.Unix(int64(metadata.Milestone.Timestamp), 0)) + } +} + +func (c *chainObj) stateOutputHandler(outputID iotago.OutputID, output iotago.Output) { + c.nodeConn.GetMetrics().GetInStateOutput().CountLastMessage(struct { + OutputID iotago.OutputID + Output iotago.Output + }{ + OutputID: outputID, + Output: output, + }) + outputIDUTXO := outputID.UTXOInput() + outputIDstring := isc.OID(outputIDUTXO) + c.log.Debugf("handling state output ID %v", outputIDstring) + aliasOutput, ok := output.(*iotago.AliasOutput) + if !ok { + c.log.Panicf("unexpected output ID %v type %T received as state update to chain ID %s; alias output expected", + outputIDstring, output, c.chainID) + } + if aliasOutput.AliasID.Empty() && aliasOutput.StateIndex != 0 { + c.log.Panicf("unexpected output ID %v index %v with empty alias ID received as state update to chain ID %s; alias ID may be empty for initial alias output only", + outputIDstring, aliasOutput.StateIndex, c.chainID) + } + if !util.AliasIDFromAliasOutput(aliasOutput, outputID).ToAddress().Equal(c.chainID.AsAddress()) { + c.log.Panicf("unexpected output ID %v address %s index %v received as state update to chain ID %s, address %s", + outputIDstring, aliasOutput.AliasID.ToAddress(), aliasOutput.StateIndex, c.chainID, c.chainID.AsAddress()) + } + c.log.Debugf("handling state output ID %v: writing alias output to channel", outputIDstring) + c.nodeConn.GetMetrics().GetInAliasOutput().CountLastMessage(aliasOutput) + c.EnqueueAliasOutput(isc.NewAliasOutputWithID(aliasOutput, outputIDUTXO)) + c.log.Debugf("handling state output ID %v: alias output handled", outputIDstring) +} + +func (c *chainObj) outputHandler(outputID iotago.OutputID, output iotago.Output) { + c.nodeConn.GetMetrics().GetInOutput().CountLastMessage(struct { + OutputID iotago.OutputID + Output iotago.Output + }{ + OutputID: outputID, + Output: output, + }) + outputIDUTXO := outputID.UTXOInput() + outputIDstring := isc.OID(outputIDUTXO) + c.log.Debugf("handling output ID %v", outputIDstring) + onLedgerRequest, err := isc.OnLedgerFromUTXO(output, outputIDUTXO) + if err != nil { + c.log.Warnf("handling output ID %v: unknown output type; ignoring it", outputIDstring) + return + } + c.log.Debugf("handling output ID %v: writing on ledger request to channel", outputIDstring) + c.nodeConn.GetMetrics().GetInOnLedgerRequest().CountLastMessage(onLedgerRequest) + c.mempool.ReceiveRequest(onLedgerRequest) + c.log.Debugf("handling output ID %v: on ledger request handled", outputIDstring) +} + +func (c *chainObj) PullLatestOutput() { + c.nodeConn.GetMetrics().GetOutPullLatestOutput().CountLastMessage(nil) + c.nodeConn.PullLatestOutput(c.chainID) +} + +func (c *chainObj) PullStateOutputByID(outputID *iotago.UTXOInput) { + c.nodeConn.GetMetrics().GetOutPullOutputByID().CountLastMessage(outputID) + c.nodeConn.PullStateOutputByID(c.chainID, outputID) +} diff --git a/packages/chain/consensus/action.go b/packages/chain/consensus/action.go index 715a118aab..47f1a060d5 100644 --- a/packages/chain/consensus/action.go +++ b/packages/chain/consensus/action.go @@ -44,7 +44,6 @@ func (c *consensus) takeAction() { c.runVMIfNeeded() c.checkQuorum() c.postTransactionIfNeeded() - c.pullInclusionStateIfNeeded() } // proposeBatchIfNeeded when non empty ready batch is available is in mempool propose it as a candidate @@ -387,8 +386,11 @@ func (c *consensus) postTransactionIfNeeded() { } var logMsgTypeStr string var logMsgStateIndexStr string + + // `c.publishTx` takes care of waiting for the tx to confirm, and handled re-attchment/promotions + c.workflow.setTransactionPosted() if c.resultState == nil { // governance transaction - if err := c.nodeConn.PublishGovernanceTransaction(c.finalTx); err != nil { + if err := c.publishTx(c.chain.ID(), c.finalTx); err != nil { c.log.Errorf("postTransaction: error publishing gov transaction: %w", err) return } @@ -396,15 +398,17 @@ func (c *consensus) postTransactionIfNeeded() { logMsgStateIndexStr = "" } else { stateIndex := c.resultState.BlockIndex() - if err := c.nodeConn.PublishStateTransaction(stateIndex, c.finalTx); err != nil { + if err := c.publishTx(c.chain.ID(), c.finalTx); err != nil { c.log.Errorf("postTransaction: error publishing state transaction: %v", err) return } logMsgTypeStr = "STATE" logMsgStateIndexStr = fmt.Sprintf(" for state %v", stateIndex) } + c.workflow.setTransactionSeen() + c.workflow.setCompleted() + c.refreshConsensusInfo() - c.workflow.setTransactionPosted() // TODO: Fix it, retries should be in place for robustness. logMsgStart := fmt.Sprintf("postTransaction: POSTED %s TRANSACTION%s:", logMsgTypeStr, logMsgStateIndexStr) logMsgEnd := fmt.Sprintf("number of inputs: %d, outputs: %d", len(c.finalTx.Essence.Inputs), len(c.finalTx.Essence.Outputs)) txID, err := c.finalTx.ID() @@ -415,30 +419,6 @@ func (c *consensus) postTransactionIfNeeded() { } } -// pullInclusionStateIfNeeded periodic pull to know the inclusions state of the transaction. Note that pulling -// starts immediately after finalization of the transaction, not after posting it -func (c *consensus) pullInclusionStateIfNeeded() { - if !c.workflow.IsTransactionFinalized() { - c.log.Debugf("pullInclusionState not needed: transaction is not finalized") - return - } - if c.workflow.IsTransactionSeen() { - c.log.Debugf("pullInclusionState not needed: transaction already seen") - return - } - if time.Now().Before(c.pullInclusionStateDeadline) { - c.log.Debugf("pullInclusionState not needed: delayed till %v", c.pullInclusionStateDeadline) - return - } - finalTxID, err := c.finalTx.ID() - if err != nil { - c.log.Panicf("pullInclusionState: cannot calculate final transaction id: %v", err) - } - c.nodeConn.PullTxInclusionState(finalTxID) - c.pullInclusionStateDeadline = time.Now().Add(c.timers.PullInclusionStateRetry) - c.log.Debugf("pullInclusionState: request for inclusion state sent") -} - // prepareBatchProposal creates a batch proposal structure out of requests func (c *consensus) prepareBatchProposal(reqs []isc.Request, dssNonceIndexProposal []int) *BatchProposal { consensusManaPledge := identity.ID{} @@ -507,7 +487,7 @@ func (c *consensus) receiveACS(values [][]byte, sessionID uint64, logIndex journ proposal, err := BatchProposalFromBytes(data) if err != nil { c.log.Errorf("receiveACS: wrong data received. Whole ACS ignored: %v", err) - c.resetWorkflow() + c.resetWorkflowNoCheck() return } acs[i] = proposal @@ -519,19 +499,19 @@ func (c *consensus) receiveACS(values [][]byte, sessionID uint64, logIndex journ if !prop.StateOutputID.Equals(c.stateOutput.ID()) { c.log.Warnf("receiveACS: ACS out of context or consensus failure: expected stateOuptudId: %v, contributor %v stateOutputID: %v ", isc.OID(c.stateOutput.ID()), prop.ValidatorIndex, isc.OID(prop.StateOutputID)) - c.resetWorkflow() + c.resetWorkflowNoCheck() return } if prop.ValidatorIndex >= c.committee.Size() { c.log.Warnf("receiveACS: wrong validator index in ACS: committee size is %v, validator index is %v", c.committee.Size(), prop.ValidatorIndex) - c.resetWorkflow() + c.resetWorkflowNoCheck() return } contributors = append(contributors, prop.ValidatorIndex) if _, already := contributorSet[prop.ValidatorIndex]; already { c.log.Errorf("receiveACS: duplicate contributor %v in ACS", prop.ValidatorIndex) - c.resetWorkflow() + c.resetWorkflowNoCheck() return } c.log.Debugf("receiveACS: contributor %v of ACS included", prop.ValidatorIndex) @@ -558,7 +538,7 @@ func (c *consensus) receiveACS(values [][]byte, sessionID uint64, logIndex journ // reached nodes and we have give it a time. Should not happen often c.log.Warnf("receiveACS: ACS intersection (light) is empty. reset workflow. State index: %d, ACS sessionID %d", c.stateOutput.GetStateIndex(), sessionID) - c.resetWorkflow() + c.resetWorkflowNoCheck() c.delayBatchProposalUntil = time.Now().Add(c.timers.ProposeBatchRetry) return } @@ -576,7 +556,7 @@ func (c *consensus) receiveACS(values [][]byte, sessionID uint64, logIndex journ // should not happen, unless insider attack c.log.Errorf("receiveACS: inconsistent ACS. Reset workflow. State index: %d, ACS sessionID %d, reason: %v", c.stateOutput.GetStateIndex(), sessionID, err) - c.resetWorkflow() + c.resetWorkflowNoCheck() c.delayBatchProposalUntil = time.Now().Add(c.timers.ProposeBatchRetry) } c.consensusBatch = &BatchProposal{ @@ -609,38 +589,6 @@ func (c *consensus) receiveACS(values [][]byte, sessionID uint64, logIndex journ c.runVMIfNeeded() } -func (c *consensus) processTxInclusionState(msg *messages.TxInclusionStateMsg) { - if !c.workflow.IsTransactionFinalized() { - c.log.Debugf("processTxInclusionState: transaction not finalized -> skipping.") - return - } - finalTxID, err := c.finalTx.ID() - finalTxIDStr := isc.TxID(finalTxID) - if err != nil { - c.log.Panicf("processTxInclusionState: cannot calculate final transaction id: %v", err) - } - if msg.TxID != finalTxID { - c.log.Debugf("processTxInclusionState: current transaction id %v does not match the received one %v -> skipping.", - finalTxIDStr, isc.TxID(msg.TxID)) - return - } - switch msg.State { - case "noTransaction": - c.log.Debugf("processTxInclusionState: transaction id %v is not known.", finalTxIDStr) - case "included": - c.workflow.setTransactionSeen() - c.workflow.setCompleted() - c.refreshConsensusInfo() - c.log.Debugf("processTxInclusionState: transaction id %s is included; workflow finished", finalTxIDStr) - case "conflicting": - c.workflow.setTransactionSeen() - c.log.Infof("processTxInclusionState: transaction id %s is conflicting; restarting consensus.", finalTxIDStr) - c.resetWorkflow() - default: - c.log.Warnf("processTxInclusionState: unknown inclusion state %s for transaction id %s; ignoring", msg.State, finalTxIDStr) - } -} - func (c *consensus) finalizeTransaction() (*iotago.Transaction, *isc.AliasOutputWithID, error) { if c.dssSignature == nil { return nil, nil, fmt.Errorf("DSS signature not ready yet") diff --git a/packages/chain/consensus/consensus.go b/packages/chain/consensus/consensus.go index 0b0230138f..b9b3a6d133 100644 --- a/packages/chain/consensus/consensus.go +++ b/packages/chain/consensus/consensus.go @@ -11,7 +11,6 @@ import ( "github.com/iotaledger/hive.go/core/logger" iotago "github.com/iotaledger/iota.go/v3" - "github.com/iotaledger/iota.go/v3/nodeclient" "github.com/iotaledger/wasp/packages/chain" "github.com/iotaledger/wasp/packages/chain/consensus/journal" dss_node "github.com/iotaledger/wasp/packages/chain/dss/node" @@ -34,7 +33,6 @@ type consensus struct { committee chain.Committee committeePeerGroup peering.GroupProvider mempool mempool_pkg.Mempool - nodeConn chain.ChainNodeConnection vmRunner vm.VMRunner currentState state.VirtualStateAccess stateOutput *isc.AliasOutputWithID @@ -62,7 +60,6 @@ type consensus struct { eventDssIndexProposalMsgPipe pipe.Pipe eventDssSignatureMsgPipe pipe.Pipe eventPeerLogIndexMsgPipe pipe.Pipe - eventInclusionStateMsgPipe pipe.Pipe eventACSMsgPipe pipe.Pipe eventVMResultMsgPipe pipe.Pipe eventTimerMsgPipe pipe.Pipe @@ -80,6 +77,7 @@ type consensus struct { consensusJournal journal.ConsensusJournal consensusJournalLogIndex journal.LogIndex // Index of the currently running log index. wal chain.WAL + publishTx func(chainID *isc.ChainID, tx *iotago.Transaction) error } var _ chain.Consensus = &consensus{} @@ -95,12 +93,12 @@ func New( mempool mempool_pkg.Mempool, committee chain.Committee, peerGroup peering.GroupProvider, - nodeConn chain.ChainNodeConnection, pullMissingRequestsFromCommittee bool, consensusMetrics metrics.ConsensusMetrics, dssNode dss_node.DSSNode, consensusJournal journal.ConsensusJournal, wal chain.WAL, + publishTx func(chainID *isc.ChainID, tx *iotago.Transaction) error, timersOpt ...ConsensusTimers, ) chain.Consensus { var timers ConsensusTimers @@ -115,7 +113,6 @@ func New( committee: committee, committeePeerGroup: peerGroup, mempool: mempool, - nodeConn: nodeConn, vmRunner: runvm.NewVMRunner(), workflow: newWorkflowStatus(false), timers: timers, @@ -124,7 +121,6 @@ func New( eventDssIndexProposalMsgPipe: pipe.NewLimitInfinitePipe(maxMsgBuffer), eventDssSignatureMsgPipe: pipe.NewLimitInfinitePipe(maxMsgBuffer), eventPeerLogIndexMsgPipe: pipe.NewLimitInfinitePipe(maxMsgBuffer), - eventInclusionStateMsgPipe: pipe.NewLimitInfinitePipe(maxMsgBuffer), eventACSMsgPipe: pipe.NewLimitInfinitePipe(maxMsgBuffer), eventVMResultMsgPipe: pipe.NewLimitInfinitePipe(maxMsgBuffer), eventTimerMsgPipe: pipe.NewLimitInfinitePipe(1), @@ -134,14 +130,9 @@ func New( dssNode: dssNode, consensusJournal: consensusJournal, wal: wal, + publishTx: publishTx, } ret.receivePeerMessagesAttachID = ret.committeePeerGroup.Attach(peering.PeerMessageReceiverConsensus, ret.receiveCommitteePeerMessages) // TODO: Don't need to attach here at all. - ret.nodeConn.AttachToMilestones(func(milestonePointer *nodeclient.MilestoneInfo) { - ret.timeData = time.Unix(int64(milestonePointer.Timestamp), 0) - }) - ret.nodeConn.AttachToTxInclusionState(func(txID iotago.TransactionID, inclusionState string) { - ret.EnqueueTxInclusionsStateMsg(txID, inclusionState) - }) ret.refreshConsensusInfo() go ret.recvLoop() return ret @@ -169,7 +160,6 @@ func (c *consensus) IsReady() bool { } func (c *consensus) Close() { - c.nodeConn.DetachFromTxInclusionState() c.committeePeerGroup.Detach(c.receivePeerMessagesAttachID) c.eventStateTransitionMsgPipe.Close() @@ -180,7 +170,6 @@ func (c *consensus) Close() { c.eventDssSignatureMsgPipe.Close() c.eventPeerLogIndexMsgPipe.Close() - c.eventInclusionStateMsgPipe.Close() c.eventACSMsgPipe.Close() c.eventVMResultMsgPipe.Close() c.eventTimerMsgPipe.Close() @@ -192,7 +181,6 @@ func (c *consensus) recvLoop() { eventDssIndexProposalMsgCh := c.eventDssIndexProposalMsgPipe.Out() eventDssSignatureMsgCh := c.eventDssSignatureMsgPipe.Out() eventPeerLogIndexMsgCh := c.eventPeerLogIndexMsgPipe.Out() - eventInclusionStateMsgCh := c.eventInclusionStateMsgPipe.Out() eventACSMsgCh := c.eventACSMsgPipe.Out() eventVMResultMsgCh := c.eventVMResultMsgPipe.Out() eventTimerMsgCh := c.eventTimerMsgPipe.Out() @@ -201,7 +189,7 @@ func (c *consensus) recvLoop() { eventDssIndexProposalMsgCh == nil && eventDssSignatureMsgCh == nil && eventPeerLogIndexMsgCh == nil && - eventInclusionStateMsgCh == nil && + // eventInclusionStateMsgCh == nil && eventACSMsgCh == nil && eventVMResultMsgCh == nil && eventTimerMsgCh == nil @@ -250,14 +238,6 @@ func (c *consensus) recvLoop() { } else { eventPeerLogIndexMsgCh = nil } - case msg, ok := <-eventInclusionStateMsgCh: - if ok { - c.log.Debugf("Consensus::recvLoop, eventTxInclusionState...") - c.handleTxInclusionState(msg.(*messages.TxInclusionStateMsg)) - c.log.Debugf("Consensus::recvLoop, eventTxInclusionState... Done") - } else { - eventInclusionStateMsgCh = nil - } case msg, ok := <-eventACSMsgCh: if ok { c.log.Debugf("Consensus::recvLoop, eventAsynchronousCommonSubset...") @@ -289,6 +269,10 @@ func (c *consensus) recvLoop() { } } +func (c *consensus) SetTimeData(t time.Time) { + c.timeData = t +} + func (c *consensus) refreshConsensusInfo() { index := uint32(0) if c.currentState != nil { @@ -333,7 +317,6 @@ func (c *consensus) GetPipeMetrics() chain.ConsensusPipeMetrics { return &pipeMetrics{ eventStateTransitionMsgPipeSize: c.eventStateTransitionMsgPipe.Len(), eventPeerLogIndexMsgPipeSize: c.eventPeerLogIndexMsgPipe.Len(), - eventInclusionStateMsgPipeSize: c.eventInclusionStateMsgPipe.Len(), eventTimerMsgPipeSize: c.eventTimerMsgPipe.Len(), eventVMResultMsgPipeSize: c.eventVMResultMsgPipe.Len(), eventACSMsgPipeSize: c.eventACSMsgPipe.Len(), diff --git a/packages/chain/consensus/consensus_test.go b/packages/chain/consensus/consensus_test.go index 352549a852..283d6fc3c6 100644 --- a/packages/chain/consensus/consensus_test.go +++ b/packages/chain/consensus/consensus_test.go @@ -14,7 +14,7 @@ import ( "github.com/iotaledger/wasp/packages/chain/consensus" ) -const waitMempoolTimeout = 3 * time.Minute +const waitMempoolTimeout = 3 * time.Minute // JS: isn't 3 minutes way too long? func TestConsensusEnvMockedACS(t *testing.T) { t.Run("wait index mocked ACS", func(t *testing.T) { diff --git a/packages/chain/consensus/eventproc.go b/packages/chain/consensus/eventproc.go index a41bbab0cc..1b9d337420 100644 --- a/packages/chain/consensus/eventproc.go +++ b/packages/chain/consensus/eventproc.go @@ -7,7 +7,6 @@ import ( "fmt" "time" - iotago "github.com/iotaledger/iota.go/v3" "github.com/iotaledger/wasp/packages/chain/messages" "github.com/iotaledger/wasp/packages/hashing" "github.com/iotaledger/wasp/packages/isc" @@ -74,20 +73,6 @@ func (c *consensus) handlePeerLogIndexMsg(msg *messages.PeerLogIndexMsgIn) { } } -func (c *consensus) EnqueueTxInclusionsStateMsg(txID iotago.TransactionID, inclusionState string) { - c.eventInclusionStateMsgPipe.In() <- &messages.TxInclusionStateMsg{ - TxID: txID, - State: inclusionState, - } -} - -func (c *consensus) handleTxInclusionState(msg *messages.TxInclusionStateMsg) { - c.log.Debugf("TxInclusionStateMsg received: %s: '%s'", isc.TxID(msg.TxID), msg.State) - c.processTxInclusionState(msg) - - c.takeAction() -} - func (c *consensus) EnqueueAsynchronousCommonSubsetMsg(msg *messages.AsynchronousCommonSubsetMsg) { c.eventACSMsgPipe.In() <- msg } diff --git a/packages/chain/consensus/mocked_node_test.go b/packages/chain/consensus/mocked_node_test.go index 94b3f0d4b0..0f39eb52b6 100644 --- a/packages/chain/consensus/mocked_node_test.go +++ b/packages/chain/consensus/mocked_node_test.go @@ -7,6 +7,7 @@ import ( "github.com/iotaledger/hive.go/core/kvstore/mapdb" "github.com/iotaledger/hive.go/core/logger" + "github.com/iotaledger/inx-app/nodebridge" iotago "github.com/iotaledger/iota.go/v3" "github.com/iotaledger/trie.go/trie" "github.com/iotaledger/wasp/packages/chain" @@ -15,7 +16,6 @@ import ( dss_node "github.com/iotaledger/wasp/packages/chain/dss/node" "github.com/iotaledger/wasp/packages/chain/mempool" "github.com/iotaledger/wasp/packages/chain/messages" - "github.com/iotaledger/wasp/packages/chain/nodeconnchain" "github.com/iotaledger/wasp/packages/cryptolib" "github.com/iotaledger/wasp/packages/isc" "github.com/iotaledger/wasp/packages/isc/coreutil" @@ -57,6 +57,7 @@ func NewNode(env *MockedEnv, nodeIndex uint16, timers ConsensusTimers) *mockedNo SolidStates: make(map[uint32]state.VirtualStateAccess), Log: log, } + ret.stateSync = coreutil.NewChainStateSync() store := mapdb.NewMapDB() ret.ChainCore.OnGlobalStateSync(func() coreutil.ChainStateSync { @@ -92,8 +93,6 @@ func NewNode(env *MockedEnv, nodeIndex uint16, timers ConsensusTimers) *mockedNo require.Equal(env.T, uint32(0), originState.BlockIndex()) require.True(env.T, ret.addNewState(originState)) - chainNodeConn, err := nodeconnchain.NewChainNodeConnection(env.ChainID, ret.NodeConn, log) - require.NoError(env.T, err) var peeringID peering.PeeringID copy(peeringID[:], env.ChainID[:]) dss := dss_node.New(&peeringID, env.NetworkProviders[nodeIndex], ret.NodeKeyPair, log) @@ -101,10 +100,22 @@ func NewNode(env *MockedEnv, nodeIndex uint16, timers ConsensusTimers) *mockedNo cmtF := cmtN - int(cmt.Quorum()) registry, err := journal.LoadConsensusJournal(*env.ChainID, cmt.Address(), testchain.NewMockedConsensusJournalRegistry(), cmtN, cmtF, log) require.NoError(env.T, err) - cons := New(ret.ChainCore, ret.Mempool, cmt, cmtPeerGroup, chainNodeConn, true, metrics.DefaultChainMetrics(), dss, registry, wal.NewDefault(), timers) + + cons := New(ret.ChainCore, ret.Mempool, cmt, cmtPeerGroup, true, metrics.DefaultChainMetrics(), dss, registry, wal.NewDefault(), ret.NodeConn.PublishTransaction, timers) cons.(*consensus).vmRunner = testchain.NewMockedVMRunner(env.T, log) ret.Consensus = cons + ret.NodeConn.RegisterChain( + env.ChainID, + func(oid iotago.OutputID, o iotago.Output) { + ret.receiveStateOutput(isc.NewAliasOutputWithID(o.(*iotago.AliasOutput), oid.UTXOInput())) + }, + func(iotago.OutputID, iotago.Output) {}, + func(metadata *nodebridge.Milestone) { + ret.Consensus.SetTimeData(time.Unix(int64(metadata.Milestone.Timestamp), 0)) + }, + ) + ret.doStateApproved(originState, env.InitStateOutput) ret.ChainCore.OnStateCandidate(func(newState state.VirtualStateAccess, approvingOutputID *iotago.UTXOInput) { // State manager mock: state candidate received and is approved by checking that L1 has approving output @@ -145,7 +156,6 @@ func NewNode(env *MockedEnv, nodeIndex uint16, timers ConsensusTimers) *mockedNo ret.doStateApproved(newState, isc.NewAliasOutputWithID(output, approvingOutputID)) }() }) - go ret.pullStateLoop() ret.Log.Debugf("Mocked node %v started: id %v public key %v", ret.NodeIndex, ret.NodeID, ret.NodeKeyPair.GetPublicKey().String()) return ret } @@ -171,22 +181,24 @@ func (n *mockedNode) addNewState(newState state.VirtualStateAccess) bool { return false } - calcState := n.getState(newStateIndex - 1) - if calcState != nil { - block, err := newState.ExtractBlock() - if err != nil { - n.Log.Panicf("State manager mock: error extracting block: %v", err) - } - calcState = calcState.Copy() - err = calcState.ApplyBlock(block) - if err != nil { - n.Log.Panicf("State manager mock: error applying to previous state: %v", err) - } - calcState.Commit() - csCommitment := trie.RootCommitment(calcState.TrieNodeStore()) - if !state.EqualCommitments(nsCommitment, csCommitment) { - n.Log.Panicf("State manager mock: calculated state commitment %s differs from new state commitment %s", - csCommitment, nsCommitment) + if newStateIndex > 0 { + calcState := n.getState(newStateIndex - 1) + if calcState != nil { + block, err := newState.ExtractBlock() + if err != nil { + n.Log.Panicf("State manager mock: error extracting block: %v", err) + } + calcState = calcState.Copy() + err = calcState.ApplyBlock(block) + if err != nil { + n.Log.Panicf("State manager mock: error applying to previous state: %v", err) + } + calcState.Commit() + csCommitment := trie.RootCommitment(calcState.TrieNodeStore()) + if !state.EqualCommitments(nsCommitment, csCommitment) { + n.Log.Panicf("State manager mock: calculated state commitment %s differs from new state commitment %s", + csCommitment, nsCommitment) + } } } @@ -254,23 +266,19 @@ func (n *mockedNode) doStateApproved(newState state.VirtualStateAccess, newState n.StateOutput.GetStateIndex(), trie.RootCommitment(newState.TrieNodeStore()), isc.OID(n.StateOutput.ID())) } -func (n *mockedNode) pullStateLoop() { // State manager mock: when node is behind and tries to catchup using state output from L1 and blocks (virtual states in mocke environment) from other nodes - for { - time.Sleep(200 * time.Millisecond) - stateOutput := n.Env.Ledgers.GetLedger(n.Env.ChainID).GetLatestOutput() - stateIndex := stateOutput.GetStateIndex() - if stateOutput != nil && (stateIndex > n.StateOutput.GetStateIndex()) { - n.Log.Debugf("State manager mock (pullStateLoop): new state output received: index %v, id %v", - stateIndex, isc.OID(stateOutput.ID())) - vstate := n.getState(stateIndex) +func (n *mockedNode) receiveStateOutput(stateOutput *isc.AliasOutputWithID) { // State manager mock: when node is behind and tries to catchup using state output from L1 and blocks (virtual states in mocke environment) from other nodes + stateIndex := stateOutput.GetStateIndex() + if stateOutput != nil && (stateIndex > n.StateOutput.GetStateIndex()) { + n.Log.Debugf("State manager mock (pullStateLoop): new state output received: index %v, id %v", + stateIndex, isc.OID(stateOutput.ID())) + vstate := n.getState(stateIndex) + if vstate == nil { + vstate = n.getStateFromNodes(stateIndex) if vstate == nil { - vstate = n.getStateFromNodes(stateIndex) - if vstate == nil { - n.Log.Panicf("State manager mock (pullStateLoop): state obtained from nodes is nil") - } + n.Log.Panicf("State manager mock (pullStateLoop): state obtained from nodes is nil") } - n.doStateApproved(vstate, stateOutput) } + n.doStateApproved(vstate, stateOutput) } } diff --git a/packages/chain/consensus/pipeMetrics.go b/packages/chain/consensus/pipeMetrics.go index 31a20b43ae..9cfb3330f2 100644 --- a/packages/chain/consensus/pipeMetrics.go +++ b/packages/chain/consensus/pipeMetrics.go @@ -3,7 +3,6 @@ package consensus type pipeMetrics struct { eventStateTransitionMsgPipeSize int eventPeerLogIndexMsgPipeSize int - eventInclusionStateMsgPipeSize int eventACSMsgPipeSize int eventVMResultMsgPipeSize int eventTimerMsgPipeSize int @@ -17,10 +16,6 @@ func (p *pipeMetrics) GetEventPeerLogIndexMsgPipeSize() int { return p.eventPeerLogIndexMsgPipeSize } -func (p *pipeMetrics) GetEventInclusionStateMsgPipeSize() int { - return p.eventInclusionStateMsgPipeSize -} - func (p *pipeMetrics) GetEventACSMsgPipeSize() int { return p.eventACSMsgPipeSize } diff --git a/packages/chain/nodeconnchain/nodeconn_chain.go b/packages/chain/nodeconnchain/nodeconn_chain.go deleted file mode 100644 index 8984cfb7d5..0000000000 --- a/packages/chain/nodeconnchain/nodeconn_chain.go +++ /dev/null @@ -1,286 +0,0 @@ -// Copyright 2020 IOTA Stiftung -// SPDX-License-Identifier: Apache-2.0 - -package nodeconnchain - -import ( - "sync" - - "github.com/iotaledger/hive.go/core/events" - "github.com/iotaledger/hive.go/core/logger" - iotago "github.com/iotaledger/iota.go/v3" - "github.com/iotaledger/wasp/packages/chain" - "github.com/iotaledger/wasp/packages/isc" - "github.com/iotaledger/wasp/packages/metrics/nodeconnmetrics" - "github.com/iotaledger/wasp/packages/util" -) - -// nodeconnChain is responsible for maintaining the information related to a single chain. -type nodeconnChain struct { - nc chain.NodeConnection - chainID *isc.ChainID - log *logger.Logger - - aliasOutputIsHandled bool - aliasOutputCh chan *isc.AliasOutputWithID - aliasOutputStopCh chan bool - onLedgerRequestIsHandled bool - onLedgerRequestCh chan isc.OnLedgerRequest - onLedgerRequestStopCh chan bool - txInclusionStateIsHandled bool - txInclusionStateCh chan *txInclusionStateMsg - txInclusionStateStopCh chan bool - txInclusionStateHandlerRef *events.Closure - milestonesHandlerRef *events.Closure - metrics nodeconnmetrics.NodeConnectionMessagesMetrics - mutex sync.Mutex // NOTE: mutexes might also be separated for aliasOutput, onLedgerRequest and txInclusionState; however, it is not going to be used heavily, so the common one is used. -} - -type txInclusionStateMsg struct { - txID iotago.TransactionID - state string -} - -var _ chain.ChainNodeConnection = &nodeconnChain{} - -func NewChainNodeConnection(chainID *isc.ChainID, nc chain.NodeConnection, log *logger.Logger) (chain.ChainNodeConnection, error) { - var err error - result := nodeconnChain{ - nc: nc, - chainID: chainID, - log: log.Named("ncc-" + chainID.String()[2:8]), - aliasOutputCh: make(chan *isc.AliasOutputWithID), - aliasOutputStopCh: make(chan bool), - onLedgerRequestCh: make(chan isc.OnLedgerRequest), - onLedgerRequestStopCh: make(chan bool), - txInclusionStateCh: make(chan *txInclusionStateMsg), - txInclusionStateStopCh: make(chan bool), - metrics: nc.GetMetrics().NewMessagesMetrics(chainID), - } - result.nc.RegisterChain(result.chainID, result.stateOutputHandler, result.outputHandler) - result.txInclusionStateHandlerRef, err = result.nc.AttachTxInclusionStateEvents(result.chainID, result.txInclusionStateHandler) - if err != nil { - result.log.Errorf("cannot create chain nodeconnection: %v", err) - return nil, err - } - result.log.Debugf("chain nodeconnection created") - return &result, nil -} - -func (nccT *nodeconnChain) stateOutputHandler(outputID iotago.OutputID, output iotago.Output) { - nccT.metrics.GetInStateOutput().CountLastMessage(struct { - OutputID iotago.OutputID - Output iotago.Output - }{ - OutputID: outputID, - Output: output, - }) - outputIDUTXO := outputID.UTXOInput() - outputIDstring := isc.OID(outputIDUTXO) - nccT.log.Debugf("handling state output ID %v", outputIDstring) - aliasOutput, ok := output.(*iotago.AliasOutput) - if !ok { - nccT.log.Panicf("unexpected output ID %v type %T received as state update to chain ID %s; alias output expected", - outputIDstring, output, nccT.chainID) - } - if aliasOutput.AliasID.Empty() && aliasOutput.StateIndex != 0 { - nccT.log.Panicf("unexpected output ID %v index %v with empty alias ID received as state update to chain ID %s; alias ID may be empty for initial alias output only", - outputIDstring, aliasOutput.StateIndex, nccT.chainID) - } - if !util.AliasIDFromAliasOutput(aliasOutput, outputID).ToAddress().Equal(nccT.chainID.AsAddress()) { - nccT.log.Panicf("unexpected output ID %v address %s index %v received as state update to chain ID %s, address %s", - outputIDstring, aliasOutput.AliasID.ToAddress(), aliasOutput.StateIndex, nccT.chainID, nccT.chainID.AsAddress()) - } - nccT.log.Debugf("handling state output ID %v: writing alias output to channel", outputIDstring) - nccT.aliasOutputCh <- isc.NewAliasOutputWithID(aliasOutput, outputIDUTXO) - nccT.log.Debugf("handling state output ID %v: alias output handled", outputIDstring) -} - -func (nccT *nodeconnChain) outputHandler(outputID iotago.OutputID, output iotago.Output) { - nccT.metrics.GetInOutput().CountLastMessage(struct { - OutputID iotago.OutputID - Output iotago.Output - }{ - OutputID: outputID, - Output: output, - }) - outputIDUTXO := outputID.UTXOInput() - outputIDstring := isc.OID(outputIDUTXO) - nccT.log.Debugf("handling output ID %v", outputIDstring) - onLedgerRequest, err := isc.OnLedgerFromUTXO(output, outputIDUTXO) - if err != nil { - nccT.log.Warnf("handling output ID %v: unknown output type; ignoring it", outputIDstring) - return - } - nccT.log.Debugf("handling output ID %v: writing on ledger request to channel", outputIDstring) - nccT.onLedgerRequestCh <- onLedgerRequest - nccT.log.Debugf("handling output ID %v: on ledger request handled", outputIDstring) -} - -func (nccT *nodeconnChain) txInclusionStateHandler(txID iotago.TransactionID, state string) { - txIDStr := isc.TxID(txID) - nccT.log.Debugf("handling inclusion state of tx ID %v: %v", txIDStr, state) - nccT.txInclusionStateCh <- &txInclusionStateMsg{ - txID: txID, - state: state, - } - nccT.log.Debugf("handling inclusion state of tx ID %v finished", txIDStr) -} - -func (nccT *nodeconnChain) AttachToAliasOutput(handler chain.NodeConnectionAliasOutputHandlerFun) { - nccT.mutex.Lock() - defer nccT.mutex.Unlock() - if nccT.aliasOutputIsHandled { - nccT.log.Errorf("alias output handler already started!") // NOTE: this should not happen; maybe panic? - return - } - nccT.aliasOutputIsHandled = true - go func() { - for { - select { - case aliasOutput := <-nccT.aliasOutputCh: - nccT.metrics.GetInAliasOutput().CountLastMessage(aliasOutput) - handler(aliasOutput) - case <-nccT.aliasOutputStopCh: - nccT.log.Debugf("alias output handler stopped") - return - } - } - }() - nccT.log.Debugf("alias output handler started") -} - -func (nccT *nodeconnChain) DetachFromAliasOutput() { - nccT.mutex.Lock() - defer nccT.mutex.Unlock() - if nccT.aliasOutputIsHandled { - nccT.aliasOutputStopCh <- true - nccT.aliasOutputIsHandled = false - } -} - -func (nccT *nodeconnChain) AttachToOnLedgerRequest(handler chain.NodeConnectionOnLedgerRequestHandlerFun) { - nccT.mutex.Lock() - defer nccT.mutex.Unlock() - if nccT.onLedgerRequestIsHandled { - nccT.log.Errorf("on ledger request handler already started!") // NOTE: this should not happen; maybe panic? - return - } - nccT.onLedgerRequestIsHandled = true - go func() { - for { - select { - case onLedgerRequest := <-nccT.onLedgerRequestCh: - nccT.metrics.GetInOnLedgerRequest().CountLastMessage(onLedgerRequest) - handler(onLedgerRequest) - case <-nccT.onLedgerRequestStopCh: - nccT.log.Debugf("on ledger request handler stopped") - return - } - } - }() - nccT.log.Debugf("on ledger request handler started") -} - -func (nccT *nodeconnChain) DetachFromOnLedgerRequest() { - nccT.mutex.Lock() - defer nccT.mutex.Unlock() - if nccT.onLedgerRequestIsHandled { - nccT.onLedgerRequestStopCh <- true - nccT.onLedgerRequestIsHandled = false - } -} - -func (nccT *nodeconnChain) AttachToTxInclusionState(handler chain.NodeConnectionInclusionStateHandlerFun) { - nccT.mutex.Lock() - defer nccT.mutex.Unlock() - if nccT.txInclusionStateIsHandled { - nccT.log.Errorf("transaction inclusion state handler already started!") - return - } - nccT.txInclusionStateIsHandled = true - go func() { - for { - select { - case msg := <-nccT.txInclusionStateCh: - nccT.metrics.GetInTxInclusionState().CountLastMessage(msg) - handler(msg.txID, msg.state) - case <-nccT.txInclusionStateStopCh: - nccT.log.Debugf("transaction inclusion state handler stopped") - return - } - } - }() - nccT.log.Debugf("transaction inclusion state handler started") -} - -func (nccT *nodeconnChain) DetachFromTxInclusionState() { - nccT.mutex.Lock() - defer nccT.mutex.Unlock() - if nccT.txInclusionStateIsHandled { - nccT.txInclusionStateStopCh <- true - nccT.txInclusionStateIsHandled = false - } -} - -func (nccT *nodeconnChain) AttachToMilestones(handler chain.NodeConnectionMilestonesHandlerFun) { - nccT.mutex.Lock() - defer nccT.mutex.Unlock() - nccT.detachFromMilestones() - nccT.milestonesHandlerRef = nccT.nc.AttachMilestones(handler) -} - -func (nccT *nodeconnChain) DetachFromMilestones() { - nccT.mutex.Lock() - defer nccT.mutex.Unlock() - nccT.detachFromMilestones() -} - -func (nccT *nodeconnChain) detachFromMilestones() { - if nccT.milestonesHandlerRef != nil { - nccT.nc.DetachMilestones(nccT.milestonesHandlerRef) - nccT.milestonesHandlerRef = nil - } -} - -func (nccT *nodeconnChain) PublishStateTransaction(stateIndex uint32, tx *iotago.Transaction) error { - nccT.metrics.GetOutPublishStateTransaction().CountLastMessage(struct { - StateIndex uint32 - Transaction *iotago.Transaction - }{ - StateIndex: stateIndex, - Transaction: tx, - }) - return nccT.nc.PublishStateTransaction(nccT.chainID, stateIndex, tx) -} - -func (nccT *nodeconnChain) PublishGovernanceTransaction(tx *iotago.Transaction) error { - nccT.metrics.GetOutPublishGovernanceTransaction().CountLastMessage(tx) - return nccT.nc.PublishGovernanceTransaction(nccT.chainID, tx) -} - -func (nccT *nodeconnChain) PullLatestOutput() { - nccT.metrics.GetOutPullLatestOutput().CountLastMessage(nil) - nccT.nc.PullLatestOutput(nccT.chainID) -} - -func (nccT *nodeconnChain) PullTxInclusionState(txID iotago.TransactionID) { - nccT.metrics.GetOutPullTxInclusionState().CountLastMessage(txID) - nccT.nc.PullTxInclusionState(nccT.chainID, txID) -} - -func (nccT *nodeconnChain) PullStateOutputByID(outputID *iotago.UTXOInput) { - nccT.metrics.GetOutPullOutputByID().CountLastMessage(outputID) - nccT.nc.PullStateOutputByID(nccT.chainID, outputID) -} - -func (nccT *nodeconnChain) GetMetrics() nodeconnmetrics.NodeConnectionMessagesMetrics { - return nccT.metrics -} - -func (nccT *nodeconnChain) Close() { - nccT.DetachFromMilestones() - _ = nccT.nc.DetachTxInclusionStateEvents(nccT.chainID, nccT.txInclusionStateHandlerRef) - nccT.nc.UnregisterChain(nccT.chainID) - nccT.log.Debugf("chain nodeconnection closed") -} diff --git a/packages/chain/statemgr/action.go b/packages/chain/statemgr/action.go index da9c98dea5..7dbef72b33 100644 --- a/packages/chain/statemgr/action.go +++ b/packages/chain/statemgr/action.go @@ -65,7 +65,7 @@ func (sm *stateManager) isSynced() bool { func (sm *stateManager) pullStateIfNeeded() { currentTime := time.Now() if currentTime.After(sm.pullStateRetryTime) { - sm.nodeConn.PullLatestOutput() + sm.nodeConn.PullLatestOutput(sm.chain.ID()) sm.pullStateRetryTime = currentTime.Add(sm.timers.PullStateRetry) sm.log.Debugf("pullState: pulling state for address %s. Next pull in: %v", sm.chain.ID().AsAddress(), sm.pullStateRetryTime.Sub(currentTime)) @@ -135,7 +135,7 @@ func (sm *stateManager) addBlockFromPeer(block state.Block) bool { if !sm.syncingBlocks.hasApprovedBlockCandidate(block.BlockIndex()) { // TODO: make the timer to not spam L1 // ask for approving output sm.log.Debugf("addBlockFromPeer: requesting approving output ID %v", isc.OID(block.ApprovingOutputID())) - sm.nodeConn.PullStateOutputByID(block.ApprovingOutputID()) + sm.nodeConn.PullStateOutputByID(sm.chain.ID(), block.ApprovingOutputID()) } return true } diff --git a/packages/chain/statemgr/mocked_node_test.go b/packages/chain/statemgr/mocked_node_test.go index 662260e182..b43954924d 100644 --- a/packages/chain/statemgr/mocked_node_test.go +++ b/packages/chain/statemgr/mocked_node_test.go @@ -11,10 +11,10 @@ import ( "github.com/iotaledger/hive.go/core/kvstore/mapdb" "github.com/iotaledger/hive.go/core/logger" + "github.com/iotaledger/inx-app/nodebridge" iotago "github.com/iotaledger/iota.go/v3" "github.com/iotaledger/wasp/packages/chain" "github.com/iotaledger/wasp/packages/chain/messages" - "github.com/iotaledger/wasp/packages/chain/nodeconnchain" "github.com/iotaledger/wasp/packages/cryptolib" "github.com/iotaledger/wasp/packages/isc" "github.com/iotaledger/wasp/packages/isc/coreutil" @@ -25,13 +25,12 @@ import ( ) type MockedNode struct { - PubKey *cryptolib.PublicKey - Env *MockedEnv - NodeConn *testchain.MockedNodeConn - ChainNodeConn chain.ChainNodeConnection - ChainCore *testchain.MockedChainCore - StateManager chain.StateManager - Log *logger.Logger + PubKey *cryptolib.PublicKey + Env *MockedEnv + NodeConn *testchain.MockedNodeConn + ChainCore *testchain.MockedChainCore + StateManager chain.StateManager + Log *logger.Logger } type MockedStateManagerMetrics struct{} @@ -64,15 +63,23 @@ func NewMockedNode(env *MockedEnv, nodeIndex int, timers StateManagerTimers) *Mo ret.ChainCore.OnGetStateReader(func() state.OptimisticStateReader { return state.NewOptimisticStateReader(store, stateSync) }) - ret.ChainNodeConn, err = nodeconnchain.NewChainNodeConnection(env.ChainID, ret.NodeConn, log) - require.NoError(env.T, err) - ret.StateManager = New(store, ret.ChainCore, stateMgrDomain, ret.ChainNodeConn, stateMgrMetrics, wal.NewDefault(), false, "", true, timers) + ret.StateManager = New(store, ret.ChainCore, stateMgrDomain, ret.NodeConn, stateMgrMetrics, wal.NewDefault(), false, "", true, timers) ret.Log.Debugf("Mocked node %v created: id %v public key %v", nodeIndex, nodeID, ret.PubKey.String()) + + ret.NodeConn.RegisterChain( + env.ChainID, + func(oid iotago.OutputID, o iotago.Output) { + ret.StateManager.EnqueueAliasOutput(isc.NewAliasOutputWithID(o.(*iotago.AliasOutput), oid.UTXOInput())) + }, + func(iotago.OutputID, iotago.Output) {}, + func(*nodebridge.Milestone) {}, + ) + return ret } func (node *MockedNode) Start() { - node.ChainNodeConn.AttachToAliasOutput(node.StateManager.EnqueueAliasOutput) + // node.ChainNodeConn.AttachToAliasOutput(node.StateManager.EnqueueAliasOutput) node.startTimer() node.Log.Debugf("Mocked node %v started", node.PubKey.String()) } @@ -124,7 +131,8 @@ func (node *MockedNode) MakeNewStateTransition() { func (node *MockedNode) NextState(vstate state.VirtualStateAccess, chainOutput *isc.AliasOutputWithID) { node.Log.Debugf("NextState: from state %d, output ID %v", vstate.BlockIndex(), isc.OID(chainOutput.ID())) nextState, tx, aliasOutputID := testchain.NextState(node.Env.T, node.Env.StateKeyPair, vstate, chainOutput, time.Now()) - go node.ChainNodeConn.PublishStateTransaction(vstate.BlockIndex(), tx) + cid := isc.ChainIDFromAliasID(chainOutput.GetAliasID()) + go node.NodeConn.PublishTransaction(&cid, tx) go node.StateManager.EnqueueStateCandidateMsg(nextState, aliasOutputID) node.Log.Debugf("NextState: result state %d, output ID %v", nextState.BlockIndex(), isc.OID(aliasOutputID)) } diff --git a/packages/chain/statemgr/statemgr.go b/packages/chain/statemgr/statemgr.go index d457cd3071..07acfe2dfa 100644 --- a/packages/chain/statemgr/statemgr.go +++ b/packages/chain/statemgr/statemgr.go @@ -30,7 +30,7 @@ type stateManager struct { store kvstore.KVStore chain chain.ChainCore domain *DomainWithFallback - nodeConn chain.ChainNodeConnection + nodeConn chain.NodeConnection pullStateRetryTime time.Time solidState state.VirtualStateAccess stateOutput *isc.AliasOutputWithID @@ -70,7 +70,7 @@ func New( store kvstore.KVStore, c chain.ChainCore, domain *DomainWithFallback, - nodeconn chain.ChainNodeConnection, + nodeconn chain.NodeConnection, stateManagerMetrics metrics.StateManagerMetrics, wal chain.WAL, rawBlocksEnabled bool, diff --git a/packages/dashboard/auth.go b/packages/dashboard/auth.go index 7cc6ee2c61..4459040218 100644 --- a/packages/dashboard/auth.go +++ b/packages/dashboard/auth.go @@ -17,6 +17,8 @@ import ( //go:embed templates/auth.tmpl var tplLogin string +const headerXForwardedPrefix = "X-Forwarded-Prefix" + func (d *Dashboard) authInit(e *echo.Echo, r renderer) Tab { e.GET(shared.AuthRouteSuccess(), d.handleAuthCheck) e.GET("/", d.handleAuthCheck) @@ -37,7 +39,7 @@ func (d *Dashboard) RenderAuthView(c echo.Context) error { auth, ok := c.Get("auth").(*authentication.AuthContext) if ok && auth.IsAuthenticated() { - return c.Redirect(http.StatusFound, "/config") + return d.redirect(c, "/config") } // TODO: Add sessions? @@ -54,14 +56,18 @@ func (d *Dashboard) handleAuthCheck(c echo.Context) error { auth, ok := c.Get("auth").(*authentication.AuthContext) if !ok { - return c.Redirect(http.StatusFound, shared.AuthRoute()) + return d.redirect(c, shared.AuthRoute()) } if auth.IsAuthenticated() { - return c.Redirect(http.StatusFound, "/config") + return d.redirect(c, "/config") } - return c.Redirect(http.StatusFound, shared.AuthRoute()) + return d.redirect(c, shared.AuthRoute()) +} + +func (d *Dashboard) redirect(c echo.Context, uri string) error { + return c.Redirect(http.StatusFound, c.Request().Header.Get(headerXForwardedPrefix)+uri) } type AuthTemplateParams struct { diff --git a/packages/dashboard/base.go b/packages/dashboard/base.go index 23928222cf..c9e5569d75 100644 --- a/packages/dashboard/base.go +++ b/packages/dashboard/base.go @@ -141,6 +141,7 @@ func (d *Dashboard) makeTemplate(e *echo.Echo, parts ...string) *template.Templa "webapiPort": d.wasp.WebAPIPort, "evmJSONRPCEndpoint": routes.EVMJSONRPC, "uri": func(s string, p ...interface{}) string { return e.Reverse(s, p...) }, + "href": func(s string) string { return s }, }) t = template.Must(t.Parse(tplBase)) for _, part := range parts { diff --git a/packages/dashboard/error.go b/packages/dashboard/error.go index 546ffeff63..29dd8af8e4 100644 --- a/packages/dashboard/error.go +++ b/packages/dashboard/error.go @@ -56,7 +56,7 @@ func (d *Dashboard) handleError(err error, c echo.Context) { authContext, ok := c.Get("auth").(*authentication.AuthContext) if ok && authContext.Scheme() == authentication.AuthJWT && he.Code == http.StatusUnauthorized { - err = c.Redirect(http.StatusFound, shared.AuthRoute()) + err = d.redirect(c, shared.AuthRoute()) } else { err = c.Render(he.Code, errorTplName, &ErrorTemplateParams{ BaseTemplateParams: d.BaseParams(c), diff --git a/packages/dashboard/renderer.go b/packages/dashboard/renderer.go index 072ba33806..b9569804ac 100644 --- a/packages/dashboard/renderer.go +++ b/packages/dashboard/renderer.go @@ -13,5 +13,12 @@ import ( type renderer map[string]*template.Template func (t renderer) Render(w io.Writer, name string, data interface{}, c echo.Context) error { - return t[name].ExecuteTemplate(w, "base", data) + return template.Must(t[name].Clone()).Funcs(template.FuncMap{ + "uri": func(s string, p ...interface{}) string { + return c.Request().Header.Get(headerXForwardedPrefix) + c.Echo().Reverse(s, p...) + }, + "href": func(s string) string { + return c.Request().Header.Get(headerXForwardedPrefix) + s + }, + }).ExecuteTemplate(w, "base", data) } diff --git a/packages/dashboard/templates/base.tmpl b/packages/dashboard/templates/base.tmpl index 62e17eabd6..c17c0799b7 100644 --- a/packages/dashboard/templates/base.tmpl +++ b/packages/dashboard/templates/base.tmpl @@ -48,7 +48,7 @@ {{ $href := index . 1 }} {{ $active := index . 2 }} - {{ .PipeMetrics.GetEventACSMsgPipeSize }}