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

Blockchain updates for L2 extension #1430

Open
wants to merge 60 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
60 commits
Select commit Hold shift + click to select a range
63b159c
Initial draft
esuwu Jun 14, 2024
69e9dbd
Changed a comment
esuwu Jun 14, 2024
b35bea1
moved a file
esuwu Jun 14, 2024
27494ad
rename a folder
esuwu Jun 14, 2024
983babc
Sent the updates channel into block appplier
esuwu Jun 20, 2024
5272899
Added some design comments
esuwu Jun 20, 2024
4fef6e3
Context in the updates function
esuwu Jun 20, 2024
dcd18f3
Merge branch 'master' into node-updates-plugin-l2
esuwu Jul 1, 2024
3cc00d5
Added protobuf
esuwu Jul 1, 2024
6752f8a
Moved proto, added conversion
esuwu Jul 16, 2024
bdc8854
Added state comparison
esuwu Jul 19, 2024
19cc302
Added a draft for retrieving history entries
esuwu Jul 22, 2024
b6fb33c
Renamed a function
esuwu Jul 22, 2024
dca31ee
Fixed most of the linter issues
esuwu Aug 1, 2024
f524fe9
Merge branch 'master' into node-updates-plugin-l2
esuwu Aug 1, 2024
18eab8c
Added paging
esuwu Aug 9, 2024
e2da71e
Added changes detector
esuwu Aug 28, 2024
da48829
Fixed a bug
esuwu Sep 12, 2024
b9318c2
Renamed functions
esuwu Sep 12, 2024
1e91dac
Merged from main
esuwu Sep 12, 2024
4dd8e5a
Merged from master
esuwu Sep 12, 2024
59f75f3
Started writing the filter
esuwu Sep 17, 2024
3a0ce55
Merged from master
esuwu Sep 17, 2024
7b77774
Commented an unused function
esuwu Sep 17, 2024
4d9419f
Added a basic filter
esuwu Oct 3, 2024
6338578
Fixed filtering
esuwu Oct 3, 2024
3d2bf74
Added tests
esuwu Oct 16, 2024
9fe8ed9
Added tests and parameters for nats subscriber
esuwu Oct 16, 2024
e057d2a
Fixed tests and linter errors
esuwu Oct 24, 2024
b2a461c
Merged from master
esuwu Oct 24, 2024
860b830
fixed gosec issues
esuwu Oct 24, 2024
ec15106
fixed one more gosec issue
esuwu Oct 24, 2024
8f70624
Mod clean.
nickeskov Nov 6, 2024
c0652df
Merge branch 'master' into node-updates-plugin-l2
nickeskov Nov 6, 2024
02f82ef
Fix lint for 'runNode' function.
nickeskov Nov 6, 2024
bb3bd64
Fix gosec issues.
nickeskov Nov 6, 2024
47320cf
Deleted stale go protobuf generated code.
nickeskov Nov 7, 2024
fb56f6b
Make some types and functions package private.
nickeskov Nov 7, 2024
89ffaf2
Update 'go.mod' go version.
nickeskov Nov 7, 2024
28086dc
Change location of 'blockchaininfo_test.go'.
nickeskov Nov 7, 2024
2f8c3c0
Add new method 'PartialBlockHeader' for 'ProtobufConverter'.
nickeskov Nov 7, 2024
5f1010c
Refactor 'BUpdatesInfoFromProto' function with unused functions removal.
nickeskov Nov 7, 2024
7dc0748
Refactored a bit 'L2ContractDataEntriesFromProto'.
nickeskov Nov 7, 2024
42bf0ff
Merge branch 'master' into node-updates-plugin-l2
nickeskov Nov 11, 2024
3f9bb83
Added a parse function
esuwu Nov 12, 2024
5d37195
Merge branch 'master' into node-updates-plugin-l2
nickeskov Nov 18, 2024
cf23bdf
Set 'NoSigs' option for nats sever to true.
nickeskov Nov 18, 2024
d7dcd5e
Fix 'runPublisher' in case when updates channel is closed.
nickeskov Nov 18, 2024
d13b940
Add nats sever shutdown.
nickeskov Nov 18, 2024
4dc94d5
Fix deadlock and refactoring.
nickeskov Nov 18, 2024
214bd46
Merge branch 'master' into node-updates-plugin-l2
nickeskov Nov 18, 2024
8fbe2b4
Fixed err not found handling
esuwu Nov 20, 2024
bb23dbc
Fixed a toolchain not found issue (#1545)
esuwu Nov 20, 2024
b65c6d9
Bump github.com/stretchr/testify from 1.9.0 to 1.10.0 (#1546)
dependabot[bot] Nov 25, 2024
68db8b3
Handle blockchain import errors properly (#1548)
nickeskov Nov 26, 2024
d66423a
Bump github.com/elliotchance/orderedmap/v2 from 2.4.0 to 2.5.0 (#1549)
dependabot[bot] Nov 28, 2024
c598d67
Check on leasing state added. (#1550)
alexeykiselev Nov 28, 2024
bd889f5
Prepare timers for go1.23. (#1552)
nickeskov Dec 2, 2024
c24cb57
Peer address parsing refactoring (#1551)
nickeskov Dec 3, 2024
6814098
Merge branch 'master' into node-updates-plugin-l2
esuwu Dec 4, 2024
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 Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,8 @@ proto:
@protoc --proto_path=pkg/grpc/protobuf-schemas/proto/ --go_out=./ --go_opt=module=$(MODULE) --go-vtproto_out=./ --go-vtproto_opt=features=marshal_strict+unmarshal+size --go-vtproto_opt=module=$(MODULE) pkg/grpc/protobuf-schemas/proto/waves/lang/*.proto
@protoc --proto_path=pkg/grpc/protobuf-schemas/proto/ --go_out=./ --go_opt=module=$(MODULE) --go-vtproto_out=./ --go-vtproto_opt=features=marshal_strict+unmarshal+size --go-vtproto_opt=module=$(MODULE) pkg/grpc/protobuf-schemas/proto/waves/events/*.proto
@protoc --proto_path=pkg/grpc/protobuf-schemas/proto/ --go_out=./ --go_opt=module=$(MODULE) --go-grpc_out=./ --go-grpc_opt=require_unimplemented_servers=false --go-grpc_opt=module=$(MODULE) pkg/grpc/protobuf-schemas/proto/waves/events/grpc/*.proto
proto-l2:
@protoc --proto_path=pkg/grpc/protobuf-schemas/proto/ --proto_path=pkg/grpc/l2/blockchain_info/ --go_out=./ --go_opt=module=$(MODULE) --go-vtproto_out=./ --go-vtproto_opt=features=marshal_strict+unmarshal+size --go-vtproto_opt=module=$(MODULE) pkg/grpc/l2/blockchain_info/*.proto

build-node-mainnet-amd64-deb-package: release-node
@mkdir -p build/dist
Expand Down
183 changes: 183 additions & 0 deletions cmd/blockchaininfo/nats_subscriber.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,183 @@
package main

import (
"context"
"encoding/json"
"flag"
"log"
"os"
"os/signal"
"strconv"
"strings"
"syscall"

"go.uber.org/zap"

"github.com/nats-io/nats.go"
"github.com/pkg/errors"
"github.com/wavesplatform/gowaves/pkg/blockchaininfo"
g "github.com/wavesplatform/gowaves/pkg/grpc/l2/blockchain_info"
"github.com/wavesplatform/gowaves/pkg/proto"
)

func printBlockInfo(blockInfoProto *g.BlockInfo) error {
blockInfo, err := blockchaininfo.BUpdatesInfoFromProto(blockInfoProto)
if err != nil {
return err
}
blockInfoJSON, err := json.Marshal(blockInfo)
if err != nil {
return err
}
log.Println(string(blockInfoJSON))
return nil
}

func printContractInfo(contractInfoProto *g.L2ContractDataEntries, scheme proto.Scheme, path string) error {
contractInfo, err := blockchaininfo.L2ContractDataEntriesFromProto(contractInfoProto, scheme)
if err != nil {
return err
}
// Delete data entries are not going to have "type"
prettyJSON, err := json.MarshalIndent(contractInfo, "", " ")
if err != nil {
log.Println("Error converting to pretty JSON:", err)
return err
}
heightStr := strconv.FormatUint(contractInfoProto.Height, 10)
// Write the pretty JSON to a file
err = os.WriteFile(path+heightStr+".json", prettyJSON, 0600)
if err != nil {
log.Println("Error writing to file:", err)
return err
}

return nil
}

func receiveBlockUpdates(msg *nats.Msg) {
blockUpdatesInfo := new(g.BlockInfo)
unmrshlErr := blockUpdatesInfo.UnmarshalVT(msg.Data)
if unmrshlErr != nil {
log.Printf("failed to unmarshal block updates, %v", unmrshlErr)
return
}

err := printBlockInfo(blockUpdatesInfo)
if err != nil {
return
}
log.Printf("Received on %s:\n", msg.Subject)
}

func receiveContractUpdates(msg *nats.Msg, contractMsg []byte, scheme proto.Scheme, path string) []byte {
zap.S().Infof("Received on %s:\n", msg.Subject)

switch msg.Data[0] {
case blockchaininfo.NoPaging:
contractMsg = msg.Data[1:]
contractUpdatesInfo := new(g.L2ContractDataEntries)
if err := contractUpdatesInfo.UnmarshalVT(contractMsg); err != nil {
log.Printf("Failed to unmarshal contract updates: %v", err)
return contractMsg
}
if err := printContractInfo(contractUpdatesInfo, scheme, path); err != nil {
log.Printf("Failed to print contract info: %v", err)
return contractMsg
}
contractMsg = nil

case blockchaininfo.StartPaging:
contractMsg = append(contractMsg, msg.Data[1:]...)

case blockchaininfo.EndPaging:
if contractMsg != nil {
contractMsg = append(contractMsg, msg.Data[1:]...)
contractUpdatesInfo := new(g.L2ContractDataEntries)
if err := contractUpdatesInfo.UnmarshalVT(contractMsg); err != nil {
log.Printf("Failed to unmarshal contract updates: %v", err)
return contractMsg
}

go func() {
if err := printContractInfo(contractUpdatesInfo, scheme, path); err != nil {
log.Printf("Failed to print contract info updates: %v", err)
}
}()
contractMsg = nil
}
}

return contractMsg
}

func main() {
var (
blockchainType string
updatesPath string
natsURL string
)
// Initialize the zap logger
l, err := zap.NewProduction()
if err != nil {
log.Fatalf("failed to initialize zap logger: %v", err)
}
defer func(l *zap.Logger) {
syncErr := l.Sync()
if syncErr != nil {
log.Fatalf("failed to sync zap logger %v", syncErr)
}
}(l)

flag.StringVar(&blockchainType, "blockchain-type", "testnet", "Blockchain scheme (e.g., stagenet, testnet, mainnet)")
flag.StringVar(&updatesPath, "updates-path", "", "File path to store contract updates")
flag.StringVar(&natsURL, "nats-url", nats.DefaultURL, "URL for the NATS server")

flag.Parse()

scheme, err := schemeFromString(blockchainType)
if err != nil {
zap.S().Fatalf("Failed to parse the blockchain type: %v", err)
}
ctx, done := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM)
defer done()
// Connect to a NATS server
nc, err := nats.Connect(natsURL)
if err != nil {
zap.S().Fatalf("Failed to connect to nats server: %v", err)
return
}
defer nc.Close()

_, err = nc.Subscribe(blockchaininfo.BlockUpdates, func(msg *nats.Msg) {
receiveBlockUpdates(msg)
})
if err != nil {
zap.S().Fatalf("Failed to subscribe to block updates: %v", err)
return
}

var contractMsg []byte
_, err = nc.Subscribe(blockchaininfo.ContractUpdates, func(msg *nats.Msg) {
contractMsg = receiveContractUpdates(msg, contractMsg, scheme, updatesPath)
})
if err != nil {
zap.S().Fatalf("Failed to subscribe to contract updates: %v", err)
return
}
<-ctx.Done()
zap.S().Info("NATS subscriber finished...")
}

func schemeFromString(networkType string) (proto.Scheme, error) {
switch strings.ToLower(networkType) {
case "mainnet":
return proto.MainNetScheme, nil
case "testnet":
return proto.TestNetScheme, nil
case "stagenet":
return proto.StageNetScheme, nil
default:
return 0, errors.New("invalid blockchain type string")
}
}
2 changes: 1 addition & 1 deletion cmd/importer/importer.go
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ func runImporter(c *cfg) error {
return err
}

st, err := state.NewState(c.dataDirPath, false, c.params(fds), ss, false)
st, err := state.NewState(c.dataDirPath, false, c.params(fds), ss, false, nil)
if err != nil {
return fmt.Errorf("failed to create state: %w", err)
}
Expand Down
136 changes: 90 additions & 46 deletions cmd/node/node.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,13 @@ import (

"github.com/pkg/errors"
"github.com/prometheus/client_golang/prometheus/promhttp"

"go.uber.org/zap"
"go.uber.org/zap/zapcore"
"golang.org/x/sync/errgroup"

"github.com/wavesplatform/gowaves/pkg/api"
"github.com/wavesplatform/gowaves/pkg/blockchaininfo"
"github.com/wavesplatform/gowaves/pkg/crypto"
"github.com/wavesplatform/gowaves/pkg/grpc/server"
"github.com/wavesplatform/gowaves/pkg/libs/microblock_cache"
Expand Down Expand Up @@ -72,51 +74,52 @@ var defaultPeers = map[string]string{
type config struct {
isParsed bool

logLevel zapcore.Level
logDevelopment bool
logNetwork bool
logNetworkData bool
logFSM bool
statePath string
blockchainType string
peerAddresses string
declAddr string
nodeName string
cfgPath string
apiAddr string
apiKey string
apiMaxConnections int
rateLimiterOptions string
grpcAddr string
grpcAPIMaxConnections int
enableMetaMaskAPI bool
enableMetaMaskAPILog bool
enableGrpcAPI bool
blackListResidenceTime time.Duration
buildExtendedAPI bool
serveExtendedAPI bool
buildStateHashes bool
bindAddress string
disableOutgoingConnections bool
minerVoteFeatures string
disableBloomFilter bool
reward int64
obsolescencePeriod time.Duration
walletPath string
walletPassword string
limitAllConnections uint
minPeersMining int
disableMiner bool
profiler bool
prometheus string
metricsID int
metricsURL string
dropPeers bool
dbFileDescriptors uint
newConnectionsLimit int
disableNTP bool
microblockInterval time.Duration
enableLightMode bool
logLevel zapcore.Level
logDevelopment bool
logNetwork bool
logNetworkData bool
logFSM bool
statePath string
blockchainType string
peerAddresses string
declAddr string
nodeName string
cfgPath string
apiAddr string
apiKey string
apiMaxConnections int
rateLimiterOptions string
grpcAddr string
grpcAPIMaxConnections int
enableMetaMaskAPI bool
enableMetaMaskAPILog bool
enableGrpcAPI bool
blackListResidenceTime time.Duration
buildExtendedAPI bool
serveExtendedAPI bool
buildStateHashes bool
bindAddress string
disableOutgoingConnections bool
minerVoteFeatures string
disableBloomFilter bool
reward int64
obsolescencePeriod time.Duration
walletPath string
walletPassword string
limitAllConnections uint
minPeersMining int
disableMiner bool
profiler bool
prometheus string
metricsID int
metricsURL string
dropPeers bool
dbFileDescriptors uint
newConnectionsLimit int
disableNTP bool
microblockInterval time.Duration
enableLightMode bool
enableBlockchainUpdatesPlugin bool
}

var errConfigNotParsed = stderrs.New("config is not parsed")
Expand Down Expand Up @@ -169,6 +172,7 @@ func (c *config) logParameters() {
zap.S().Debugf("disable-ntp: %t", c.disableNTP)
zap.S().Debugf("microblock-interval: %s", c.microblockInterval)
zap.S().Debugf("enable-light-mode: %t", c.enableLightMode)
zap.S().Debugf("enable-blockchain-updates-plugin: %t", c.enableBlockchainUpdatesPlugin)
}

func (c *config) parse() {
Expand Down Expand Up @@ -266,6 +270,9 @@ func (c *config) parse() {
"Interval between microblocks.")
flag.BoolVar(&c.enableLightMode, "enable-light-mode", false,
"Start node in light mode")

flag.BoolVar(&c.enableBlockchainUpdatesPlugin, "enable-blockchain-info", false,
"Turn on blockchain updates plugin")
flag.Parse()
c.logLevel = *l
}
Expand Down Expand Up @@ -393,7 +400,17 @@ func runNode(ctx context.Context, nc *config) (_ io.Closer, retErr error) {
return nil, errors.Wrap(err, "failed to create state parameters")
}

st, err := state.NewState(path, true, params, cfg, nc.enableLightMode)
var bUpdatesExtension *blockchaininfo.BlockchainUpdatesExtension
if nc.enableBlockchainUpdatesPlugin {
var bUErr error
bUpdatesExtension, bUErr = runBlockchainUpdatesPlugin(ctx, cfg)
if bUErr != nil {
return nil, errors.Wrap(bUErr, "failed to run blockchain updates plugin")
}
}

// Send updatesChannel into BlockchainSettings. Write updates into this channel
st, err := state.NewState(path, true, params, cfg, nc.enableLightMode, bUpdatesExtension)
if err != nil {
return nil, errors.Wrap(err, "failed to initialize node's state")
}
Expand Down Expand Up @@ -795,6 +812,33 @@ func runAPIs(
return nil
}

func runBlockchainUpdatesPlugin(
ctx context.Context,
cfg *settings.BlockchainSettings,
) (*blockchaininfo.BlockchainUpdatesExtension, error) {
const l2ContractAddr = "3Msx4Aq69zWUKy4d1wyKnQ4ofzEDAfv5Ngf"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This parameter must be configurable.


l2address, cnvrtErr := proto.NewAddressFromString(l2ContractAddr)
if cnvrtErr != nil {
return nil, errors.Wrapf(cnvrtErr, "failed to convert L2 contract address %q", l2ContractAddr)
}

bUpdatesExtensionState := blockchaininfo.NewBUpdatesExtensionState(
blockchaininfo.StoreBlocksLimit,
cfg.AddressSchemeCharacter,
)

updatesChannel := make(chan blockchaininfo.BUpdatesInfo)
go func() {
err := bUpdatesExtensionState.RunBlockchainUpdatesPublisher(ctx, updatesChannel, cfg.AddressSchemeCharacter)
if err != nil {
zap.S().Fatalf("Failed to run blockchain updates publisher: %v", err)
}
}()

return blockchaininfo.NewBlockchainUpdatesExtension(ctx, l2address, updatesChannel), nil
}

func FromArgs(scheme proto.Scheme, c *config) func(s *settings.NodeSettings) error {
return func(s *settings.NodeSettings) error {
s.DeclaredAddr = c.declAddr
Expand Down
2 changes: 1 addition & 1 deletion cmd/rollback/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ func main() {
params.BuildStateHashes = *buildStateHashes
params.StoreExtendedApiData = *buildExtendedAPI

s, err := state.NewState(*statePath, true, params, cfg, false)
s, err := state.NewState(*statePath, true, params, cfg, false, nil)
if err != nil {
zap.S().Error(err)
return
Expand Down
Loading
Loading