From d97753e9e5ac57a7bef9778e93a888d36d30ec2d Mon Sep 17 00:00:00 2001 From: Rapol Date: Wed, 14 Aug 2024 11:07:03 +0200 Subject: [PATCH 01/27] actually add protobuf --- protobuf/substate.proto | 119 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 119 insertions(+) create mode 100644 protobuf/substate.proto diff --git a/protobuf/substate.proto b/protobuf/substate.proto new file mode 100644 index 0000000..54efaa5 --- /dev/null +++ b/protobuf/substate.proto @@ -0,0 +1,119 @@ +yntax = "proto2"; +package research; + +// For a single optional bytes, use `optional BytesValue` +// For an optional list of bytes, use `repeated bytes` +import "google/protobuf/wrappers.proto"; + +option go_package = "../research"; + +message Substate { + + message Account { + required uint64 nonce = 1; + required bytes balance = 2; + + message StorageEntry { + required bytes key = 1; + required bytes value = 2; + } + repeated StorageEntry storage = 3; + + oneof contract { + bytes code = 4; + bytes code_hash = 5; + } + } + message AllocEntry { + required bytes address = 1; + required Account account = 2; + } + message Alloc { + repeated AllocEntry alloc = 1; + } + required Alloc input_alloc = 1; + required Alloc output_alloc = 2; + + message BlockEnv { + required bytes coinbase = 1; + required bytes difficulty = 2; + required uint64 gas_limit = 3; + required uint64 number = 4; + required uint64 timestamp = 5; + + message BlockHashEntry { + required uint64 key = 1; + required bytes value = 2; + } + repeated BlockHashEntry block_hashes = 6; + // London hard fork introduced BASEFEE instruction + optional google.protobuf.BytesValue base_fee = 7; + // The Merge hard fork replaced DIFFICULTY with PREVRANDAO + optional google.protobuf.BytesValue random = 8; + // Cancun hard fork introduced BLOBBASEFEE instruction + optional google.protobuf.BytesValue blob_base_fee = 9; + } + required BlockEnv block_env = 3; + + message TxMessage { + required uint64 nonce = 1; + required bytes gas_price = 2; + required uint64 gas = 3; + + required bytes from = 4; + // TxMessage.to is nil for contract creation + optional google.protobuf.BytesValue to = 5; + required bytes value = 6; + + oneof input { + bytes data = 7; + bytes init_code_hash = 8; + } + + enum TxType { + TXTYPE_LEGACY = 0; + // Berlin hard fork introduced optional access list + TXTYPE_ACCESSLIST = 1; + // London hard fork introduced optional dynamic fee market + TXTYPE_DYNAMICFEE = 2; + // Cancun hard fork introduced optional tx blob + TXTYPE_BLOB = 3; + } + required TxType tx_type = 9; + + // AccessList from TXTYPE_ACCESSLIST + // nil for tx types prior to TXTYPE_ACCESSLIST + message AccessListEntry { + required bytes address = 1; + repeated bytes storage_keys = 2; + } + repeated AccessListEntry access_list = 10; + + // GasFeeCap, GasTipCap from TXTYPE_DYNAMICFEE + // nil for tx types prior to TXTYPE_DYNAMICFEE + optional google.protobuf.BytesValue gas_fee_cap = 11; + optional google.protobuf.BytesValue gas_tip_cap = 12; + + // BlobFeeCap, BlobHashes, optional Sidecar from TXTYPE_BLOB + // nil for tx types prior to TXTYPE_BLOB + optional google.protobuf.BytesValue blob_gas_fee_cap = 13; + repeated bytes blob_hashes = 14; + } + required TxMessage tx_message = 4; + + message Result { + required uint64 status = 1; + required bytes bloom = 2; + + message Log { + required bytes address = 1; + repeated bytes topics = 2; + required bytes data = 3; + } + repeated Log logs = 3; + + required uint64 gas_used = 4; + } + required Result result = 5; + +} From 1fb0b27936a009c56231a2bd7972c13297692696 Mon Sep 17 00:00:00 2001 From: Rapol Date: Mon, 23 Sep 2024 09:51:28 +0200 Subject: [PATCH 02/27] squash and sign --- db/code_db.go | 1 + db/substate_db.go | 2 + protobuf/decode.go | 283 ++++++++ protobuf/protoc-substate.sh | 5 + protobuf/substate.pb.go | 1339 +++++++++++++++++++++++++++++++++++ protobuf/substate.proto | 6 +- protobuf/utils.go | 31 + rlp/rlp_account.go | 2 +- rlp/rlp_world_state.go | 6 +- substate/account.go | 6 +- substate/env.go | 2 + substate/substate.go | 21 + substate/world_state.go | 6 +- types/uint256.go | 31 + updateset/update_set.go | 2 +- 15 files changed, 1731 insertions(+), 12 deletions(-) create mode 100644 protobuf/decode.go create mode 100644 protobuf/protoc-substate.sh create mode 100644 protobuf/substate.pb.go create mode 100644 protobuf/utils.go create mode 100644 types/uint256.go diff --git a/db/code_db.go b/db/code_db.go index 49755c3..0fed13b 100644 --- a/db/code_db.go +++ b/db/code_db.go @@ -88,6 +88,7 @@ func (db *codeDB) GetCode(codeHash types.Hash) ([]byte, error) { if err != nil { return nil, fmt.Errorf("cannot get code %s: %w", codeHash, err) } + return code, nil } diff --git a/db/substate_db.go b/db/substate_db.go index 904d8c1..74bbe9f 100644 --- a/db/substate_db.go +++ b/db/substate_db.go @@ -4,9 +4,11 @@ import ( "encoding/binary" "fmt" + pb "github.com/Fantom-foundation/Substate/protobuf" "github.com/Fantom-foundation/Substate/rlp" "github.com/Fantom-foundation/Substate/substate" trlp "github.com/Fantom-foundation/Substate/types/rlp" + "github.com/golang/protobuf/proto" "github.com/syndtr/goleveldb/leveldb" "github.com/syndtr/goleveldb/leveldb/opt" "github.com/syndtr/goleveldb/leveldb/util" diff --git a/protobuf/decode.go b/protobuf/decode.go new file mode 100644 index 0000000..73116d7 --- /dev/null +++ b/protobuf/decode.go @@ -0,0 +1,283 @@ +package protobuf + +import ( + "errors" + "fmt" + "math/big" + + "github.com/Fantom-foundation/Substate/substate" + "github.com/Fantom-foundation/Substate/types" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/crypto" + "github.com/holiman/uint256" + "github.com/syndtr/goleveldb/leveldb" +) + +type dbGetCode = func(types.Hash) ([]byte, error) + +// Decode converts protobuf-encoded Substate into aida-comprehensible substate +func (s *Substate) Decode(lookup dbGetCode, block uint64, tx int) (*substate.Substate, error) { + input, err := s.GetInputAlloc().decode(lookup) + if err != nil { + return nil, err + } + + output, err := s.GetOutputAlloc().decode(lookup) + if err != nil { + return nil, err + } + + environment, err := s.GetBlockEnv().decode() + if err != nil { + return nil, err + } + + message, err := s.GetTxMessage().decode(lookup) + if err != nil { + return nil, err + } + + contractAddress := s.GetTxMessage().getContractAddress() + result, err := s.GetResult().decode(contractAddress) + if err != nil { + return nil, err + } + + return &substate.Substate{ + InputSubstate: *input, + OutputSubstate: *output, + Env: environment, + Message: message, + Result: result, + Block: block, + Transaction: tx, + }, nil +} + +// decode converts protobuf-encoded Substate_Alloc into aida-comprehensible WorldState +func (alloc *Substate_Alloc) decode(lookup dbGetCode) (*substate.WorldState, error) { + world := make(substate.WorldState, len(alloc.GetAlloc())) + + for _, entry := range alloc.GetAlloc() { + addr, acct, err := entry.decode() + if err != nil { + return nil, fmt.Errorf("Error decoding alloc entry; %w", err) + } + + address := types.BytesToAddress(addr) + nonce, balance, _, codehash, err := acct.decode() + if err != nil { + return nil, fmt.Errorf("Error decoding entry account; %w", err) + } + + code, err := lookup(codehash) + if err != nil && !errors.Is(err, leveldb.ErrNotFound) { + return nil, fmt.Errorf("Error looking up codehash; %w", err) + } + + world[address] = substate.NewAccount(nonce, balance, code) + for _, storage := range acct.GetStorage() { + key, value, err := storage.decode() + if err != nil { + return nil, fmt.Errorf("Error decoding account storage entry; %w", err) + } + world[address].Storage[key] = value + } + } + + return &world, nil +} + +func (entry *Substate_AllocEntry) decode() ([]byte, *Substate_Account, error) { + return entry.GetAddress(), entry.GetAccount(), nil +} + +func (acct *Substate_Account) decode() (uint64, *uint256.Int, []byte, types.Hash, error) { + return acct.GetNonce(), + types.BytesToUint256(acct.GetBalance()), + acct.GetCode(), + types.BytesToHash(acct.GetCodeHash()), + nil +} + +func (entry *Substate_Account_StorageEntry) decode() (types.Hash, types.Hash, error) { + return types.BytesToHash(entry.GetKey()), + types.BytesToHash(entry.GetValue()), + nil +} + +// decode converts protobuf-encoded Substate_BlockEnv into aida-comprehensible Env +func (env *Substate_BlockEnv) decode() (*substate.Env, error) { + var blockHashes map[uint64]types.Hash = nil + if env.GetBlockHashes() != nil { + blockHashes = make(map[uint64]types.Hash, len(env.GetBlockHashes())) + for _, entry := range env.GetBlockHashes() { + key, value, err := entry.decode() + if err != nil { + return nil, err + } + blockHashes[key] = types.BytesToHash(value) + } + } + + return &substate.Env{ + Coinbase: types.BytesToAddress(env.GetCoinbase()), + Difficulty: types.BytesToBigInt(env.GetDifficulty()), + GasLimit: env.GetGasLimit(), + Number: env.GetNumber(), + Timestamp: env.GetTimestamp(), + BlockHashes: blockHashes, + BaseFee: BytesValueToBigInt(env.GetBaseFee()), + Random: BytesValueToHash(env.GetRandom()), + BlobBaseFee: BytesValueToBigInt(env.GetBlobBaseFee()), + }, nil +} + +func (entry *Substate_BlockEnv_BlockHashEntry) decode() (uint64, []byte, error) { + return entry.GetKey(), entry.GetValue(), nil +} + +// decode converts protobuf-encoded Substate_TxMessage into aida-comprehensible Message +func (msg *Substate_TxMessage) decode(lookup dbGetCode) (*substate.Message, error) { + + // to=nil means contract creation + var pTo *types.Address = nil + to := msg.GetTo() + if to != nil { + address := types.BytesToAddress(to.GetValue()) + pTo = &address + } + + // if InitCodeHash exists: + // 1. code = lookup the code using InitCodeHash + // 2. set data -> code from (1) + // 3. clear InitCodeHash + var data []byte = msg.GetData() + if pTo == nil { + code, err := lookup(types.BytesToHash(msg.GetInitCodeHash())) + if err != nil && !errors.Is(err, leveldb.ErrNotFound) { + return nil, fmt.Errorf("failed to decode tx message; %w", err) + } + data = code + } + + txType := msg.GetTxType() + + // Berlin hard fork, EIP-2930: Optional access lists + var accessList types.AccessList = nil // nil if EIP-2930 is not activated + switch txType { + case Substate_TxMessage_TXTYPE_ACCESSLIST, + Substate_TxMessage_TXTYPE_DYNAMICFEE, + Substate_TxMessage_TXTYPE_BLOB: + + accessList = make([]types.AccessTuple, len(msg.GetAccessList())) + for i, entry := range msg.GetAccessList() { + addr, keys, err := entry.decode() + if err != nil { + return nil, err + } + + address := types.BytesToAddress(addr) + storageKeys := make([]types.Hash, len(keys)) + for j, key := range keys { + storageKeys[j] = types.BytesToHash(key) + } + + accessList[i] = types.AccessTuple{ + Address: address, + StorageKeys: storageKeys, + } + } + } + + // London hard fork, EIP-1559: Fee market + var gasFeeCap *big.Int = types.BytesToBigInt(msg.GetGasPrice()) + var gasTipCap *big.Int = types.BytesToBigInt(msg.GetGasPrice()) + switch txType { + case Substate_TxMessage_TXTYPE_DYNAMICFEE, + Substate_TxMessage_TXTYPE_BLOB: + + gasFeeCap = BytesValueToBigInt(msg.GetGasFeeCap()) + gasTipCap = BytesValueToBigInt(msg.GetGasTipCap()) + } + + // Cancun hard fork, EIP-4844 + var blobHashes []types.Hash = nil + switch txType { + case Substate_TxMessage_TXTYPE_BLOB: + if msg.GetBlobHashes() != nil { + blobHashes = make([]types.Hash, len(msg.GetBlobHashes())) + for i, hash := range msg.GetBlobHashes() { + blobHashes[i] = types.BytesToHash(hash) + } + } + } + + return &substate.Message{ + Nonce: msg.GetNonce(), + CheckNonce: true, + GasPrice: types.BytesToBigInt(msg.GetGasPrice()), + Gas: msg.GetGas(), + From: types.BytesToAddress(msg.GetFrom()), + To: pTo, + Value: types.BytesToBigInt(msg.GetValue()), + Data: data, + AccessList: accessList, + GasFeeCap: gasFeeCap, + GasTipCap: gasTipCap, + BlobGasFeeCap: BytesValueToBigInt(msg.GetBlobGasFeeCap()), + BlobHashes: blobHashes, + }, nil +} + +func (entry *Substate_TxMessage_AccessListEntry) decode() ([]byte, [][]byte, error) { + return entry.GetAddress(), entry.GetStorageKeys(), nil +} + +// getContractAddress returns the address of the newly created contract if any. +// returns nil otherwise. +func (msg *Substate_TxMessage) getContractAddress() common.Address { + var contractAddress common.Address + + // *to==nil means contract creation and thus address of newly created contract + to := msg.GetTo() + if to == nil { + fromAddr := common.BytesToAddress(msg.GetFrom()) + contractAddress = crypto.CreateAddress(fromAddr, msg.GetNonce()) + } + + return contractAddress +} + +// decode converts protobuf-encoded Substate_Result into aida-comprehensible Result +func (res *Substate_Result) decode(contractAddress common.Address) (*substate.Result, error) { + var err error = nil + logs := make([]*types.Log, len(res.GetLogs())) + for i, log := range res.GetLogs() { + logs[i], err = log.decode() + if err != nil { + return nil, fmt.Errorf("Error decoding result; %w", err) + } + } + + return substate.NewResult( + res.GetStatus(), // Status + types.BytesToBloom(res.Bloom), // Bloom + logs, // Logs + types.BytesToAddress(contractAddress.Bytes()), // ContractAddress + res.GetGasUsed(), // GasUsed + ), nil +} + +func (log *Substate_Result_Log) decode() (*types.Log, error) { + topics := make([]types.Hash, len(log.GetTopics())) + for i, topic := range log.GetTopics() { + topics[i] = types.BytesToHash(topic) + } + + return &types.Log{ + Address: types.BytesToAddress(log.GetAddress()), + Topics: topics, + Data: log.GetData(), + }, nil +} diff --git a/protobuf/protoc-substate.sh b/protobuf/protoc-substate.sh new file mode 100644 index 0000000..9625e81 --- /dev/null +++ b/protobuf/protoc-substate.sh @@ -0,0 +1,5 @@ +#!/bin/bash + +#go install google.golang.org/protobuf/cmd/protoc-gen-go@v1.28.1 + +protoc --go_out=. substate.proto diff --git a/protobuf/substate.pb.go b/protobuf/substate.pb.go new file mode 100644 index 0000000..e4b7765 --- /dev/null +++ b/protobuf/substate.pb.go @@ -0,0 +1,1339 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.28.1 +// protoc v3.21.12 +// source: substate.proto + +package protobuf + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + wrapperspb "google.golang.org/protobuf/types/known/wrapperspb" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type Substate_TxMessage_TxType int32 + +const ( + Substate_TxMessage_TXTYPE_LEGACY Substate_TxMessage_TxType = 0 + // Berlin hard fork introduced optional access list + Substate_TxMessage_TXTYPE_ACCESSLIST Substate_TxMessage_TxType = 1 + // London hard fork introduced optional dynamic fee market + Substate_TxMessage_TXTYPE_DYNAMICFEE Substate_TxMessage_TxType = 2 + // Cancun hard fork introduced optional tx blob + Substate_TxMessage_TXTYPE_BLOB Substate_TxMessage_TxType = 3 +) + +// Enum value maps for Substate_TxMessage_TxType. +var ( + Substate_TxMessage_TxType_name = map[int32]string{ + 0: "TXTYPE_LEGACY", + 1: "TXTYPE_ACCESSLIST", + 2: "TXTYPE_DYNAMICFEE", + 3: "TXTYPE_BLOB", + } + Substate_TxMessage_TxType_value = map[string]int32{ + "TXTYPE_LEGACY": 0, + "TXTYPE_ACCESSLIST": 1, + "TXTYPE_DYNAMICFEE": 2, + "TXTYPE_BLOB": 3, + } +) + +func (x Substate_TxMessage_TxType) Enum() *Substate_TxMessage_TxType { + p := new(Substate_TxMessage_TxType) + *p = x + return p +} + +func (x Substate_TxMessage_TxType) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (Substate_TxMessage_TxType) Descriptor() protoreflect.EnumDescriptor { + return file_substate_proto_enumTypes[0].Descriptor() +} + +func (Substate_TxMessage_TxType) Type() protoreflect.EnumType { + return &file_substate_proto_enumTypes[0] +} + +func (x Substate_TxMessage_TxType) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Do not use. +func (x *Substate_TxMessage_TxType) UnmarshalJSON(b []byte) error { + num, err := protoimpl.X.UnmarshalJSONEnum(x.Descriptor(), b) + if err != nil { + return err + } + *x = Substate_TxMessage_TxType(num) + return nil +} + +// Deprecated: Use Substate_TxMessage_TxType.Descriptor instead. +func (Substate_TxMessage_TxType) EnumDescriptor() ([]byte, []int) { + return file_substate_proto_rawDescGZIP(), []int{0, 4, 0} +} + +type Substate struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + InputAlloc *Substate_Alloc `protobuf:"bytes,1,req,name=input_alloc,json=inputAlloc" json:"input_alloc,omitempty"` + OutputAlloc *Substate_Alloc `protobuf:"bytes,2,req,name=output_alloc,json=outputAlloc" json:"output_alloc,omitempty"` + BlockEnv *Substate_BlockEnv `protobuf:"bytes,3,req,name=block_env,json=blockEnv" json:"block_env,omitempty"` + TxMessage *Substate_TxMessage `protobuf:"bytes,4,req,name=tx_message,json=txMessage" json:"tx_message,omitempty"` + Result *Substate_Result `protobuf:"bytes,5,req,name=result" json:"result,omitempty"` +} + +func (x *Substate) Reset() { + *x = Substate{} + if protoimpl.UnsafeEnabled { + mi := &file_substate_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Substate) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Substate) ProtoMessage() {} + +func (x *Substate) ProtoReflect() protoreflect.Message { + mi := &file_substate_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Substate.ProtoReflect.Descriptor instead. +func (*Substate) Descriptor() ([]byte, []int) { + return file_substate_proto_rawDescGZIP(), []int{0} +} + +func (x *Substate) GetInputAlloc() *Substate_Alloc { + if x != nil { + return x.InputAlloc + } + return nil +} + +func (x *Substate) GetOutputAlloc() *Substate_Alloc { + if x != nil { + return x.OutputAlloc + } + return nil +} + +func (x *Substate) GetBlockEnv() *Substate_BlockEnv { + if x != nil { + return x.BlockEnv + } + return nil +} + +func (x *Substate) GetTxMessage() *Substate_TxMessage { + if x != nil { + return x.TxMessage + } + return nil +} + +func (x *Substate) GetResult() *Substate_Result { + if x != nil { + return x.Result + } + return nil +} + +type Substate_Account struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Nonce *uint64 `protobuf:"varint,1,req,name=nonce" json:"nonce,omitempty"` + Balance []byte `protobuf:"bytes,2,req,name=balance" json:"balance,omitempty"` + Storage []*Substate_Account_StorageEntry `protobuf:"bytes,3,rep,name=storage" json:"storage,omitempty"` + // Types that are assignable to Contract: + // + // *Substate_Account_Code + // *Substate_Account_CodeHash + Contract isSubstate_Account_Contract `protobuf_oneof:"contract"` +} + +func (x *Substate_Account) Reset() { + *x = Substate_Account{} + if protoimpl.UnsafeEnabled { + mi := &file_substate_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Substate_Account) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Substate_Account) ProtoMessage() {} + +func (x *Substate_Account) ProtoReflect() protoreflect.Message { + mi := &file_substate_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Substate_Account.ProtoReflect.Descriptor instead. +func (*Substate_Account) Descriptor() ([]byte, []int) { + return file_substate_proto_rawDescGZIP(), []int{0, 0} +} + +func (x *Substate_Account) GetNonce() uint64 { + if x != nil && x.Nonce != nil { + return *x.Nonce + } + return 0 +} + +func (x *Substate_Account) GetBalance() []byte { + if x != nil { + return x.Balance + } + return nil +} + +func (x *Substate_Account) GetStorage() []*Substate_Account_StorageEntry { + if x != nil { + return x.Storage + } + return nil +} + +func (m *Substate_Account) GetContract() isSubstate_Account_Contract { + if m != nil { + return m.Contract + } + return nil +} + +func (x *Substate_Account) GetCode() []byte { + if x, ok := x.GetContract().(*Substate_Account_Code); ok { + return x.Code + } + return nil +} + +func (x *Substate_Account) GetCodeHash() []byte { + if x, ok := x.GetContract().(*Substate_Account_CodeHash); ok { + return x.CodeHash + } + return nil +} + +type isSubstate_Account_Contract interface { + isSubstate_Account_Contract() +} + +type Substate_Account_Code struct { + Code []byte `protobuf:"bytes,4,opt,name=code,oneof"` +} + +type Substate_Account_CodeHash struct { + CodeHash []byte `protobuf:"bytes,5,opt,name=code_hash,json=codeHash,oneof"` +} + +func (*Substate_Account_Code) isSubstate_Account_Contract() {} + +func (*Substate_Account_CodeHash) isSubstate_Account_Contract() {} + +type Substate_AllocEntry struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Address []byte `protobuf:"bytes,1,req,name=address" json:"address,omitempty"` + Account *Substate_Account `protobuf:"bytes,2,req,name=account" json:"account,omitempty"` +} + +func (x *Substate_AllocEntry) Reset() { + *x = Substate_AllocEntry{} + if protoimpl.UnsafeEnabled { + mi := &file_substate_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Substate_AllocEntry) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Substate_AllocEntry) ProtoMessage() {} + +func (x *Substate_AllocEntry) ProtoReflect() protoreflect.Message { + mi := &file_substate_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Substate_AllocEntry.ProtoReflect.Descriptor instead. +func (*Substate_AllocEntry) Descriptor() ([]byte, []int) { + return file_substate_proto_rawDescGZIP(), []int{0, 1} +} + +func (x *Substate_AllocEntry) GetAddress() []byte { + if x != nil { + return x.Address + } + return nil +} + +func (x *Substate_AllocEntry) GetAccount() *Substate_Account { + if x != nil { + return x.Account + } + return nil +} + +type Substate_Alloc struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Alloc []*Substate_AllocEntry `protobuf:"bytes,1,rep,name=alloc" json:"alloc,omitempty"` +} + +func (x *Substate_Alloc) Reset() { + *x = Substate_Alloc{} + if protoimpl.UnsafeEnabled { + mi := &file_substate_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Substate_Alloc) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Substate_Alloc) ProtoMessage() {} + +func (x *Substate_Alloc) ProtoReflect() protoreflect.Message { + mi := &file_substate_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Substate_Alloc.ProtoReflect.Descriptor instead. +func (*Substate_Alloc) Descriptor() ([]byte, []int) { + return file_substate_proto_rawDescGZIP(), []int{0, 2} +} + +func (x *Substate_Alloc) GetAlloc() []*Substate_AllocEntry { + if x != nil { + return x.Alloc + } + return nil +} + +type Substate_BlockEnv struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Coinbase []byte `protobuf:"bytes,1,req,name=coinbase" json:"coinbase,omitempty"` + Difficulty []byte `protobuf:"bytes,2,req,name=difficulty" json:"difficulty,omitempty"` + GasLimit *uint64 `protobuf:"varint,3,req,name=gas_limit,json=gasLimit" json:"gas_limit,omitempty"` + Number *uint64 `protobuf:"varint,4,req,name=number" json:"number,omitempty"` + Timestamp *uint64 `protobuf:"varint,5,req,name=timestamp" json:"timestamp,omitempty"` + BlockHashes []*Substate_BlockEnv_BlockHashEntry `protobuf:"bytes,6,rep,name=block_hashes,json=blockHashes" json:"block_hashes,omitempty"` + // London hard fork introduced BASEFEE instruction + BaseFee *wrapperspb.BytesValue `protobuf:"bytes,7,opt,name=base_fee,json=baseFee" json:"base_fee,omitempty"` + // The Merge hard fork replaced DIFFICULTY with PREVRANDAO + Random *wrapperspb.BytesValue `protobuf:"bytes,8,opt,name=random" json:"random,omitempty"` + // Cancun hard fork introduced BLOBBASEFEE instruction + BlobBaseFee *wrapperspb.BytesValue `protobuf:"bytes,9,opt,name=blob_base_fee,json=blobBaseFee" json:"blob_base_fee,omitempty"` +} + +func (x *Substate_BlockEnv) Reset() { + *x = Substate_BlockEnv{} + if protoimpl.UnsafeEnabled { + mi := &file_substate_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Substate_BlockEnv) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Substate_BlockEnv) ProtoMessage() {} + +func (x *Substate_BlockEnv) ProtoReflect() protoreflect.Message { + mi := &file_substate_proto_msgTypes[4] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Substate_BlockEnv.ProtoReflect.Descriptor instead. +func (*Substate_BlockEnv) Descriptor() ([]byte, []int) { + return file_substate_proto_rawDescGZIP(), []int{0, 3} +} + +func (x *Substate_BlockEnv) GetCoinbase() []byte { + if x != nil { + return x.Coinbase + } + return nil +} + +func (x *Substate_BlockEnv) GetDifficulty() []byte { + if x != nil { + return x.Difficulty + } + return nil +} + +func (x *Substate_BlockEnv) GetGasLimit() uint64 { + if x != nil && x.GasLimit != nil { + return *x.GasLimit + } + return 0 +} + +func (x *Substate_BlockEnv) GetNumber() uint64 { + if x != nil && x.Number != nil { + return *x.Number + } + return 0 +} + +func (x *Substate_BlockEnv) GetTimestamp() uint64 { + if x != nil && x.Timestamp != nil { + return *x.Timestamp + } + return 0 +} + +func (x *Substate_BlockEnv) GetBlockHashes() []*Substate_BlockEnv_BlockHashEntry { + if x != nil { + return x.BlockHashes + } + return nil +} + +func (x *Substate_BlockEnv) GetBaseFee() *wrapperspb.BytesValue { + if x != nil { + return x.BaseFee + } + return nil +} + +func (x *Substate_BlockEnv) GetRandom() *wrapperspb.BytesValue { + if x != nil { + return x.Random + } + return nil +} + +func (x *Substate_BlockEnv) GetBlobBaseFee() *wrapperspb.BytesValue { + if x != nil { + return x.BlobBaseFee + } + return nil +} + +type Substate_TxMessage struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Nonce *uint64 `protobuf:"varint,1,req,name=nonce" json:"nonce,omitempty"` + GasPrice []byte `protobuf:"bytes,2,req,name=gas_price,json=gasPrice" json:"gas_price,omitempty"` + Gas *uint64 `protobuf:"varint,3,req,name=gas" json:"gas,omitempty"` + From []byte `protobuf:"bytes,4,req,name=from" json:"from,omitempty"` + // TxMessage.to is nil for contract creation + To *wrapperspb.BytesValue `protobuf:"bytes,5,opt,name=to" json:"to,omitempty"` + Value []byte `protobuf:"bytes,6,req,name=value" json:"value,omitempty"` + // Types that are assignable to Input: + // + // *Substate_TxMessage_Data + // *Substate_TxMessage_InitCodeHash + Input isSubstate_TxMessage_Input `protobuf_oneof:"input"` + TxType *Substate_TxMessage_TxType `protobuf:"varint,9,req,name=tx_type,json=txType,enum=protobuf.Substate_TxMessage_TxType" json:"tx_type,omitempty"` + AccessList []*Substate_TxMessage_AccessListEntry `protobuf:"bytes,10,rep,name=access_list,json=accessList" json:"access_list,omitempty"` + // GasFeeCap, GasTipCap from TXTYPE_DYNAMICFEE + // nil for tx types prior to TXTYPE_DYNAMICFEE + GasFeeCap *wrapperspb.BytesValue `protobuf:"bytes,11,opt,name=gas_fee_cap,json=gasFeeCap" json:"gas_fee_cap,omitempty"` + GasTipCap *wrapperspb.BytesValue `protobuf:"bytes,12,opt,name=gas_tip_cap,json=gasTipCap" json:"gas_tip_cap,omitempty"` + // BlobFeeCap, BlobHashes, optional Sidecar from TXTYPE_BLOB + // nil for tx types prior to TXTYPE_BLOB + BlobGasFeeCap *wrapperspb.BytesValue `protobuf:"bytes,13,opt,name=blob_gas_fee_cap,json=blobGasFeeCap" json:"blob_gas_fee_cap,omitempty"` + BlobHashes [][]byte `protobuf:"bytes,14,rep,name=blob_hashes,json=blobHashes" json:"blob_hashes,omitempty"` +} + +func (x *Substate_TxMessage) Reset() { + *x = Substate_TxMessage{} + if protoimpl.UnsafeEnabled { + mi := &file_substate_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Substate_TxMessage) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Substate_TxMessage) ProtoMessage() {} + +func (x *Substate_TxMessage) ProtoReflect() protoreflect.Message { + mi := &file_substate_proto_msgTypes[5] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Substate_TxMessage.ProtoReflect.Descriptor instead. +func (*Substate_TxMessage) Descriptor() ([]byte, []int) { + return file_substate_proto_rawDescGZIP(), []int{0, 4} +} + +func (x *Substate_TxMessage) GetNonce() uint64 { + if x != nil && x.Nonce != nil { + return *x.Nonce + } + return 0 +} + +func (x *Substate_TxMessage) GetGasPrice() []byte { + if x != nil { + return x.GasPrice + } + return nil +} + +func (x *Substate_TxMessage) GetGas() uint64 { + if x != nil && x.Gas != nil { + return *x.Gas + } + return 0 +} + +func (x *Substate_TxMessage) GetFrom() []byte { + if x != nil { + return x.From + } + return nil +} + +func (x *Substate_TxMessage) GetTo() *wrapperspb.BytesValue { + if x != nil { + return x.To + } + return nil +} + +func (x *Substate_TxMessage) GetValue() []byte { + if x != nil { + return x.Value + } + return nil +} + +func (m *Substate_TxMessage) GetInput() isSubstate_TxMessage_Input { + if m != nil { + return m.Input + } + return nil +} + +func (x *Substate_TxMessage) GetData() []byte { + if x, ok := x.GetInput().(*Substate_TxMessage_Data); ok { + return x.Data + } + return nil +} + +func (x *Substate_TxMessage) GetInitCodeHash() []byte { + if x, ok := x.GetInput().(*Substate_TxMessage_InitCodeHash); ok { + return x.InitCodeHash + } + return nil +} + +func (x *Substate_TxMessage) GetTxType() Substate_TxMessage_TxType { + if x != nil && x.TxType != nil { + return *x.TxType + } + return Substate_TxMessage_TXTYPE_LEGACY +} + +func (x *Substate_TxMessage) GetAccessList() []*Substate_TxMessage_AccessListEntry { + if x != nil { + return x.AccessList + } + return nil +} + +func (x *Substate_TxMessage) GetGasFeeCap() *wrapperspb.BytesValue { + if x != nil { + return x.GasFeeCap + } + return nil +} + +func (x *Substate_TxMessage) GetGasTipCap() *wrapperspb.BytesValue { + if x != nil { + return x.GasTipCap + } + return nil +} + +func (x *Substate_TxMessage) GetBlobGasFeeCap() *wrapperspb.BytesValue { + if x != nil { + return x.BlobGasFeeCap + } + return nil +} + +func (x *Substate_TxMessage) GetBlobHashes() [][]byte { + if x != nil { + return x.BlobHashes + } + return nil +} + +type isSubstate_TxMessage_Input interface { + isSubstate_TxMessage_Input() +} + +type Substate_TxMessage_Data struct { + Data []byte `protobuf:"bytes,7,opt,name=data,oneof"` +} + +type Substate_TxMessage_InitCodeHash struct { + InitCodeHash []byte `protobuf:"bytes,8,opt,name=init_code_hash,json=initCodeHash,oneof"` +} + +func (*Substate_TxMessage_Data) isSubstate_TxMessage_Input() {} + +func (*Substate_TxMessage_InitCodeHash) isSubstate_TxMessage_Input() {} + +type Substate_Result struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Status *uint64 `protobuf:"varint,1,req,name=status" json:"status,omitempty"` + Bloom []byte `protobuf:"bytes,2,req,name=bloom" json:"bloom,omitempty"` + Logs []*Substate_Result_Log `protobuf:"bytes,3,rep,name=logs" json:"logs,omitempty"` + GasUsed *uint64 `protobuf:"varint,4,req,name=gas_used,json=gasUsed" json:"gas_used,omitempty"` +} + +func (x *Substate_Result) Reset() { + *x = Substate_Result{} + if protoimpl.UnsafeEnabled { + mi := &file_substate_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Substate_Result) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Substate_Result) ProtoMessage() {} + +func (x *Substate_Result) ProtoReflect() protoreflect.Message { + mi := &file_substate_proto_msgTypes[6] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Substate_Result.ProtoReflect.Descriptor instead. +func (*Substate_Result) Descriptor() ([]byte, []int) { + return file_substate_proto_rawDescGZIP(), []int{0, 5} +} + +func (x *Substate_Result) GetStatus() uint64 { + if x != nil && x.Status != nil { + return *x.Status + } + return 0 +} + +func (x *Substate_Result) GetBloom() []byte { + if x != nil { + return x.Bloom + } + return nil +} + +func (x *Substate_Result) GetLogs() []*Substate_Result_Log { + if x != nil { + return x.Logs + } + return nil +} + +func (x *Substate_Result) GetGasUsed() uint64 { + if x != nil && x.GasUsed != nil { + return *x.GasUsed + } + return 0 +} + +type Substate_Account_StorageEntry struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Key []byte `protobuf:"bytes,1,req,name=key" json:"key,omitempty"` + Value []byte `protobuf:"bytes,2,req,name=value" json:"value,omitempty"` +} + +func (x *Substate_Account_StorageEntry) Reset() { + *x = Substate_Account_StorageEntry{} + if protoimpl.UnsafeEnabled { + mi := &file_substate_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Substate_Account_StorageEntry) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Substate_Account_StorageEntry) ProtoMessage() {} + +func (x *Substate_Account_StorageEntry) ProtoReflect() protoreflect.Message { + mi := &file_substate_proto_msgTypes[7] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Substate_Account_StorageEntry.ProtoReflect.Descriptor instead. +func (*Substate_Account_StorageEntry) Descriptor() ([]byte, []int) { + return file_substate_proto_rawDescGZIP(), []int{0, 0, 0} +} + +func (x *Substate_Account_StorageEntry) GetKey() []byte { + if x != nil { + return x.Key + } + return nil +} + +func (x *Substate_Account_StorageEntry) GetValue() []byte { + if x != nil { + return x.Value + } + return nil +} + +type Substate_BlockEnv_BlockHashEntry struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Key *uint64 `protobuf:"varint,1,req,name=key" json:"key,omitempty"` + Value []byte `protobuf:"bytes,2,req,name=value" json:"value,omitempty"` +} + +func (x *Substate_BlockEnv_BlockHashEntry) Reset() { + *x = Substate_BlockEnv_BlockHashEntry{} + if protoimpl.UnsafeEnabled { + mi := &file_substate_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Substate_BlockEnv_BlockHashEntry) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Substate_BlockEnv_BlockHashEntry) ProtoMessage() {} + +func (x *Substate_BlockEnv_BlockHashEntry) ProtoReflect() protoreflect.Message { + mi := &file_substate_proto_msgTypes[8] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Substate_BlockEnv_BlockHashEntry.ProtoReflect.Descriptor instead. +func (*Substate_BlockEnv_BlockHashEntry) Descriptor() ([]byte, []int) { + return file_substate_proto_rawDescGZIP(), []int{0, 3, 0} +} + +func (x *Substate_BlockEnv_BlockHashEntry) GetKey() uint64 { + if x != nil && x.Key != nil { + return *x.Key + } + return 0 +} + +func (x *Substate_BlockEnv_BlockHashEntry) GetValue() []byte { + if x != nil { + return x.Value + } + return nil +} + +// AccessList from TXTYPE_ACCESSLIST +// nil for tx types prior to TXTYPE_ACCESSLIST +type Substate_TxMessage_AccessListEntry struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Address []byte `protobuf:"bytes,1,req,name=address" json:"address,omitempty"` + StorageKeys [][]byte `protobuf:"bytes,2,rep,name=storage_keys,json=storageKeys" json:"storage_keys,omitempty"` +} + +func (x *Substate_TxMessage_AccessListEntry) Reset() { + *x = Substate_TxMessage_AccessListEntry{} + if protoimpl.UnsafeEnabled { + mi := &file_substate_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Substate_TxMessage_AccessListEntry) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Substate_TxMessage_AccessListEntry) ProtoMessage() {} + +func (x *Substate_TxMessage_AccessListEntry) ProtoReflect() protoreflect.Message { + mi := &file_substate_proto_msgTypes[9] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Substate_TxMessage_AccessListEntry.ProtoReflect.Descriptor instead. +func (*Substate_TxMessage_AccessListEntry) Descriptor() ([]byte, []int) { + return file_substate_proto_rawDescGZIP(), []int{0, 4, 0} +} + +func (x *Substate_TxMessage_AccessListEntry) GetAddress() []byte { + if x != nil { + return x.Address + } + return nil +} + +func (x *Substate_TxMessage_AccessListEntry) GetStorageKeys() [][]byte { + if x != nil { + return x.StorageKeys + } + return nil +} + +type Substate_Result_Log struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Address []byte `protobuf:"bytes,1,req,name=address" json:"address,omitempty"` + Topics [][]byte `protobuf:"bytes,2,rep,name=topics" json:"topics,omitempty"` + Data []byte `protobuf:"bytes,3,req,name=data" json:"data,omitempty"` +} + +func (x *Substate_Result_Log) Reset() { + *x = Substate_Result_Log{} + if protoimpl.UnsafeEnabled { + mi := &file_substate_proto_msgTypes[10] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Substate_Result_Log) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Substate_Result_Log) ProtoMessage() {} + +func (x *Substate_Result_Log) ProtoReflect() protoreflect.Message { + mi := &file_substate_proto_msgTypes[10] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Substate_Result_Log.ProtoReflect.Descriptor instead. +func (*Substate_Result_Log) Descriptor() ([]byte, []int) { + return file_substate_proto_rawDescGZIP(), []int{0, 5, 0} +} + +func (x *Substate_Result_Log) GetAddress() []byte { + if x != nil { + return x.Address + } + return nil +} + +func (x *Substate_Result_Log) GetTopics() [][]byte { + if x != nil { + return x.Topics + } + return nil +} + +func (x *Substate_Result_Log) GetData() []byte { + if x != nil { + return x.Data + } + return nil +} + +var File_substate_proto protoreflect.FileDescriptor + +var file_substate_proto_rawDesc = []byte{ + 0x0a, 0x0e, 0x73, 0x75, 0x62, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x12, 0x08, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x1a, 0x1e, 0x67, 0x6f, 0x6f, 0x67, + 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x77, 0x72, 0x61, 0x70, + 0x70, 0x65, 0x72, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xf2, 0x10, 0x0a, 0x08, 0x53, + 0x75, 0x62, 0x73, 0x74, 0x61, 0x74, 0x65, 0x12, 0x39, 0x0a, 0x0b, 0x69, 0x6e, 0x70, 0x75, 0x74, + 0x5f, 0x61, 0x6c, 0x6c, 0x6f, 0x63, 0x18, 0x01, 0x20, 0x02, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x75, 0x62, 0x73, 0x74, 0x61, 0x74, 0x65, + 0x2e, 0x41, 0x6c, 0x6c, 0x6f, 0x63, 0x52, 0x0a, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x41, 0x6c, 0x6c, + 0x6f, 0x63, 0x12, 0x3b, 0x0a, 0x0c, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x5f, 0x61, 0x6c, 0x6c, + 0x6f, 0x63, 0x18, 0x02, 0x20, 0x02, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x62, 0x75, 0x66, 0x2e, 0x53, 0x75, 0x62, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x41, 0x6c, 0x6c, + 0x6f, 0x63, 0x52, 0x0b, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x41, 0x6c, 0x6c, 0x6f, 0x63, 0x12, + 0x38, 0x0a, 0x09, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x65, 0x6e, 0x76, 0x18, 0x03, 0x20, 0x02, + 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x75, + 0x62, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x45, 0x6e, 0x76, 0x52, + 0x08, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x45, 0x6e, 0x76, 0x12, 0x3b, 0x0a, 0x0a, 0x74, 0x78, 0x5f, + 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x04, 0x20, 0x02, 0x28, 0x0b, 0x32, 0x1c, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x75, 0x62, 0x73, 0x74, 0x61, 0x74, + 0x65, 0x2e, 0x54, 0x78, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x09, 0x74, 0x78, 0x4d, + 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x31, 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, + 0x18, 0x05, 0x20, 0x02, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, + 0x66, 0x2e, 0x53, 0x75, 0x62, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x52, 0x65, 0x73, 0x75, 0x6c, + 0x74, 0x52, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x1a, 0xf5, 0x01, 0x0a, 0x07, 0x41, 0x63, + 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x18, 0x01, + 0x20, 0x02, 0x28, 0x04, 0x52, 0x05, 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x62, + 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x18, 0x02, 0x20, 0x02, 0x28, 0x0c, 0x52, 0x07, 0x62, 0x61, + 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x12, 0x41, 0x0a, 0x07, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, + 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, + 0x66, 0x2e, 0x53, 0x75, 0x62, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x41, 0x63, 0x63, 0x6f, 0x75, + 0x6e, 0x74, 0x2e, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, + 0x07, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x12, 0x14, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x48, 0x00, 0x52, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x12, 0x1d, + 0x0a, 0x09, 0x63, 0x6f, 0x64, 0x65, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x05, 0x20, 0x01, 0x28, + 0x0c, 0x48, 0x00, 0x52, 0x08, 0x63, 0x6f, 0x64, 0x65, 0x48, 0x61, 0x73, 0x68, 0x1a, 0x36, 0x0a, + 0x0c, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, + 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x02, 0x28, 0x0c, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, + 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x02, 0x28, 0x0c, 0x52, 0x05, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x0a, 0x0a, 0x08, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, + 0x74, 0x1a, 0x5c, 0x0a, 0x0a, 0x41, 0x6c, 0x6c, 0x6f, 0x63, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, + 0x18, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x02, 0x28, 0x0c, + 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x34, 0x0a, 0x07, 0x61, 0x63, 0x63, + 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x02, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x75, 0x62, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x41, + 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x07, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x1a, + 0x3c, 0x0a, 0x05, 0x41, 0x6c, 0x6c, 0x6f, 0x63, 0x12, 0x33, 0x0a, 0x05, 0x61, 0x6c, 0x6c, 0x6f, + 0x63, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, + 0x75, 0x66, 0x2e, 0x53, 0x75, 0x62, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x41, 0x6c, 0x6c, 0x6f, + 0x63, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x05, 0x61, 0x6c, 0x6c, 0x6f, 0x63, 0x1a, 0xd0, 0x03, + 0x0a, 0x08, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x45, 0x6e, 0x76, 0x12, 0x1a, 0x0a, 0x08, 0x63, 0x6f, + 0x69, 0x6e, 0x62, 0x61, 0x73, 0x65, 0x18, 0x01, 0x20, 0x02, 0x28, 0x0c, 0x52, 0x08, 0x63, 0x6f, + 0x69, 0x6e, 0x62, 0x61, 0x73, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x64, 0x69, 0x66, 0x66, 0x69, 0x63, + 0x75, 0x6c, 0x74, 0x79, 0x18, 0x02, 0x20, 0x02, 0x28, 0x0c, 0x52, 0x0a, 0x64, 0x69, 0x66, 0x66, + 0x69, 0x63, 0x75, 0x6c, 0x74, 0x79, 0x12, 0x1b, 0x0a, 0x09, 0x67, 0x61, 0x73, 0x5f, 0x6c, 0x69, + 0x6d, 0x69, 0x74, 0x18, 0x03, 0x20, 0x02, 0x28, 0x04, 0x52, 0x08, 0x67, 0x61, 0x73, 0x4c, 0x69, + 0x6d, 0x69, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x04, 0x20, + 0x02, 0x28, 0x04, 0x52, 0x06, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x1c, 0x0a, 0x09, 0x74, + 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x05, 0x20, 0x02, 0x28, 0x04, 0x52, 0x09, + 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x4d, 0x0a, 0x0c, 0x62, 0x6c, 0x6f, + 0x63, 0x6b, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x65, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x2a, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x75, 0x62, 0x73, 0x74, + 0x61, 0x74, 0x65, 0x2e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x45, 0x6e, 0x76, 0x2e, 0x42, 0x6c, 0x6f, + 0x63, 0x6b, 0x48, 0x61, 0x73, 0x68, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0b, 0x62, 0x6c, 0x6f, + 0x63, 0x6b, 0x48, 0x61, 0x73, 0x68, 0x65, 0x73, 0x12, 0x36, 0x0a, 0x08, 0x62, 0x61, 0x73, 0x65, + 0x5f, 0x66, 0x65, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x67, 0x6f, 0x6f, + 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x42, 0x79, 0x74, + 0x65, 0x73, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x07, 0x62, 0x61, 0x73, 0x65, 0x46, 0x65, 0x65, + 0x12, 0x33, 0x0a, 0x06, 0x72, 0x61, 0x6e, 0x64, 0x6f, 0x6d, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x1b, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, + 0x75, 0x66, 0x2e, 0x42, 0x79, 0x74, 0x65, 0x73, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x06, 0x72, + 0x61, 0x6e, 0x64, 0x6f, 0x6d, 0x12, 0x3f, 0x0a, 0x0d, 0x62, 0x6c, 0x6f, 0x62, 0x5f, 0x62, 0x61, + 0x73, 0x65, 0x5f, 0x66, 0x65, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x67, + 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x42, + 0x79, 0x74, 0x65, 0x73, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0b, 0x62, 0x6c, 0x6f, 0x62, 0x42, + 0x61, 0x73, 0x65, 0x46, 0x65, 0x65, 0x1a, 0x38, 0x0a, 0x0e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x48, + 0x61, 0x73, 0x68, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, + 0x01, 0x20, 0x02, 0x28, 0x04, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, + 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x02, 0x28, 0x0c, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, + 0x1a, 0x88, 0x06, 0x0a, 0x09, 0x54, 0x78, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x14, + 0x0a, 0x05, 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x18, 0x01, 0x20, 0x02, 0x28, 0x04, 0x52, 0x05, 0x6e, + 0x6f, 0x6e, 0x63, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x67, 0x61, 0x73, 0x5f, 0x70, 0x72, 0x69, 0x63, + 0x65, 0x18, 0x02, 0x20, 0x02, 0x28, 0x0c, 0x52, 0x08, 0x67, 0x61, 0x73, 0x50, 0x72, 0x69, 0x63, + 0x65, 0x12, 0x10, 0x0a, 0x03, 0x67, 0x61, 0x73, 0x18, 0x03, 0x20, 0x02, 0x28, 0x04, 0x52, 0x03, + 0x67, 0x61, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x66, 0x72, 0x6f, 0x6d, 0x18, 0x04, 0x20, 0x02, 0x28, + 0x0c, 0x52, 0x04, 0x66, 0x72, 0x6f, 0x6d, 0x12, 0x2b, 0x0a, 0x02, 0x74, 0x6f, 0x18, 0x05, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x42, 0x79, 0x74, 0x65, 0x73, 0x56, 0x61, 0x6c, 0x75, 0x65, + 0x52, 0x02, 0x74, 0x6f, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x06, 0x20, + 0x02, 0x28, 0x0c, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x14, 0x0a, 0x04, 0x64, 0x61, + 0x74, 0x61, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0c, 0x48, 0x00, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, + 0x12, 0x26, 0x0a, 0x0e, 0x69, 0x6e, 0x69, 0x74, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x5f, 0x68, 0x61, + 0x73, 0x68, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0c, 0x48, 0x00, 0x52, 0x0c, 0x69, 0x6e, 0x69, 0x74, + 0x43, 0x6f, 0x64, 0x65, 0x48, 0x61, 0x73, 0x68, 0x12, 0x3c, 0x0a, 0x07, 0x74, 0x78, 0x5f, 0x74, + 0x79, 0x70, 0x65, 0x18, 0x09, 0x20, 0x02, 0x28, 0x0e, 0x32, 0x23, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x75, 0x62, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x54, 0x78, + 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x54, 0x78, 0x54, 0x79, 0x70, 0x65, 0x52, 0x06, + 0x74, 0x78, 0x54, 0x79, 0x70, 0x65, 0x12, 0x4d, 0x0a, 0x0b, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, + 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x18, 0x0a, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x75, 0x62, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, + 0x54, 0x78, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, + 0x4c, 0x69, 0x73, 0x74, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0a, 0x61, 0x63, 0x63, 0x65, 0x73, + 0x73, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x3b, 0x0a, 0x0b, 0x67, 0x61, 0x73, 0x5f, 0x66, 0x65, 0x65, + 0x5f, 0x63, 0x61, 0x70, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x67, 0x6f, 0x6f, + 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x42, 0x79, 0x74, + 0x65, 0x73, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x09, 0x67, 0x61, 0x73, 0x46, 0x65, 0x65, 0x43, + 0x61, 0x70, 0x12, 0x3b, 0x0a, 0x0b, 0x67, 0x61, 0x73, 0x5f, 0x74, 0x69, 0x70, 0x5f, 0x63, 0x61, + 0x70, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x42, 0x79, 0x74, 0x65, 0x73, 0x56, + 0x61, 0x6c, 0x75, 0x65, 0x52, 0x09, 0x67, 0x61, 0x73, 0x54, 0x69, 0x70, 0x43, 0x61, 0x70, 0x12, + 0x44, 0x0a, 0x10, 0x62, 0x6c, 0x6f, 0x62, 0x5f, 0x67, 0x61, 0x73, 0x5f, 0x66, 0x65, 0x65, 0x5f, + 0x63, 0x61, 0x70, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x67, 0x6f, 0x6f, 0x67, + 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x42, 0x79, 0x74, 0x65, + 0x73, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0d, 0x62, 0x6c, 0x6f, 0x62, 0x47, 0x61, 0x73, 0x46, + 0x65, 0x65, 0x43, 0x61, 0x70, 0x12, 0x1f, 0x0a, 0x0b, 0x62, 0x6c, 0x6f, 0x62, 0x5f, 0x68, 0x61, + 0x73, 0x68, 0x65, 0x73, 0x18, 0x0e, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x0a, 0x62, 0x6c, 0x6f, 0x62, + 0x48, 0x61, 0x73, 0x68, 0x65, 0x73, 0x1a, 0x4e, 0x0a, 0x0f, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, + 0x4c, 0x69, 0x73, 0x74, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x64, 0x64, + 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x02, 0x28, 0x0c, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, + 0x65, 0x73, 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x5f, 0x6b, + 0x65, 0x79, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x0b, 0x73, 0x74, 0x6f, 0x72, 0x61, + 0x67, 0x65, 0x4b, 0x65, 0x79, 0x73, 0x22, 0x5a, 0x0a, 0x06, 0x54, 0x78, 0x54, 0x79, 0x70, 0x65, + 0x12, 0x11, 0x0a, 0x0d, 0x54, 0x58, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x4c, 0x45, 0x47, 0x41, 0x43, + 0x59, 0x10, 0x00, 0x12, 0x15, 0x0a, 0x11, 0x54, 0x58, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x41, 0x43, + 0x43, 0x45, 0x53, 0x53, 0x4c, 0x49, 0x53, 0x54, 0x10, 0x01, 0x12, 0x15, 0x0a, 0x11, 0x54, 0x58, + 0x54, 0x59, 0x50, 0x45, 0x5f, 0x44, 0x59, 0x4e, 0x41, 0x4d, 0x49, 0x43, 0x46, 0x45, 0x45, 0x10, + 0x02, 0x12, 0x0f, 0x0a, 0x0b, 0x54, 0x58, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x42, 0x4c, 0x4f, 0x42, + 0x10, 0x03, 0x42, 0x07, 0x0a, 0x05, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x1a, 0xd1, 0x01, 0x0a, 0x06, + 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, + 0x18, 0x01, 0x20, 0x02, 0x28, 0x04, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x14, + 0x0a, 0x05, 0x62, 0x6c, 0x6f, 0x6f, 0x6d, 0x18, 0x02, 0x20, 0x02, 0x28, 0x0c, 0x52, 0x05, 0x62, + 0x6c, 0x6f, 0x6f, 0x6d, 0x12, 0x31, 0x0a, 0x04, 0x6c, 0x6f, 0x67, 0x73, 0x18, 0x03, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x75, + 0x62, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x2e, 0x4c, 0x6f, + 0x67, 0x52, 0x04, 0x6c, 0x6f, 0x67, 0x73, 0x12, 0x19, 0x0a, 0x08, 0x67, 0x61, 0x73, 0x5f, 0x75, + 0x73, 0x65, 0x64, 0x18, 0x04, 0x20, 0x02, 0x28, 0x04, 0x52, 0x07, 0x67, 0x61, 0x73, 0x55, 0x73, + 0x65, 0x64, 0x1a, 0x4b, 0x0a, 0x03, 0x4c, 0x6f, 0x67, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x64, 0x64, + 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x02, 0x28, 0x0c, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, + 0x65, 0x73, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x74, 0x6f, 0x70, 0x69, 0x63, 0x73, 0x18, 0x02, 0x20, + 0x03, 0x28, 0x0c, 0x52, 0x06, 0x74, 0x6f, 0x70, 0x69, 0x63, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x64, + 0x61, 0x74, 0x61, 0x18, 0x03, 0x20, 0x02, 0x28, 0x0c, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x42, + 0x0d, 0x5a, 0x0b, 0x2e, 0x2e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, +} + +var ( + file_substate_proto_rawDescOnce sync.Once + file_substate_proto_rawDescData = file_substate_proto_rawDesc +) + +func file_substate_proto_rawDescGZIP() []byte { + file_substate_proto_rawDescOnce.Do(func() { + file_substate_proto_rawDescData = protoimpl.X.CompressGZIP(file_substate_proto_rawDescData) + }) + return file_substate_proto_rawDescData +} + +var file_substate_proto_enumTypes = make([]protoimpl.EnumInfo, 1) +var file_substate_proto_msgTypes = make([]protoimpl.MessageInfo, 11) +var file_substate_proto_goTypes = []interface{}{ + (Substate_TxMessage_TxType)(0), // 0: protobuf.Substate.TxMessage.TxType + (*Substate)(nil), // 1: protobuf.Substate + (*Substate_Account)(nil), // 2: protobuf.Substate.Account + (*Substate_AllocEntry)(nil), // 3: protobuf.Substate.AllocEntry + (*Substate_Alloc)(nil), // 4: protobuf.Substate.Alloc + (*Substate_BlockEnv)(nil), // 5: protobuf.Substate.BlockEnv + (*Substate_TxMessage)(nil), // 6: protobuf.Substate.TxMessage + (*Substate_Result)(nil), // 7: protobuf.Substate.Result + (*Substate_Account_StorageEntry)(nil), // 8: protobuf.Substate.Account.StorageEntry + (*Substate_BlockEnv_BlockHashEntry)(nil), // 9: protobuf.Substate.BlockEnv.BlockHashEntry + (*Substate_TxMessage_AccessListEntry)(nil), // 10: protobuf.Substate.TxMessage.AccessListEntry + (*Substate_Result_Log)(nil), // 11: protobuf.Substate.Result.Log + (*wrapperspb.BytesValue)(nil), // 12: google.protobuf.BytesValue +} +var file_substate_proto_depIdxs = []int32{ + 4, // 0: protobuf.Substate.input_alloc:type_name -> protobuf.Substate.Alloc + 4, // 1: protobuf.Substate.output_alloc:type_name -> protobuf.Substate.Alloc + 5, // 2: protobuf.Substate.block_env:type_name -> protobuf.Substate.BlockEnv + 6, // 3: protobuf.Substate.tx_message:type_name -> protobuf.Substate.TxMessage + 7, // 4: protobuf.Substate.result:type_name -> protobuf.Substate.Result + 8, // 5: protobuf.Substate.Account.storage:type_name -> protobuf.Substate.Account.StorageEntry + 2, // 6: protobuf.Substate.AllocEntry.account:type_name -> protobuf.Substate.Account + 3, // 7: protobuf.Substate.Alloc.alloc:type_name -> protobuf.Substate.AllocEntry + 9, // 8: protobuf.Substate.BlockEnv.block_hashes:type_name -> protobuf.Substate.BlockEnv.BlockHashEntry + 12, // 9: protobuf.Substate.BlockEnv.base_fee:type_name -> google.protobuf.BytesValue + 12, // 10: protobuf.Substate.BlockEnv.random:type_name -> google.protobuf.BytesValue + 12, // 11: protobuf.Substate.BlockEnv.blob_base_fee:type_name -> google.protobuf.BytesValue + 12, // 12: protobuf.Substate.TxMessage.to:type_name -> google.protobuf.BytesValue + 0, // 13: protobuf.Substate.TxMessage.tx_type:type_name -> protobuf.Substate.TxMessage.TxType + 10, // 14: protobuf.Substate.TxMessage.access_list:type_name -> protobuf.Substate.TxMessage.AccessListEntry + 12, // 15: protobuf.Substate.TxMessage.gas_fee_cap:type_name -> google.protobuf.BytesValue + 12, // 16: protobuf.Substate.TxMessage.gas_tip_cap:type_name -> google.protobuf.BytesValue + 12, // 17: protobuf.Substate.TxMessage.blob_gas_fee_cap:type_name -> google.protobuf.BytesValue + 11, // 18: protobuf.Substate.Result.logs:type_name -> protobuf.Substate.Result.Log + 19, // [19:19] is the sub-list for method output_type + 19, // [19:19] is the sub-list for method input_type + 19, // [19:19] is the sub-list for extension type_name + 19, // [19:19] is the sub-list for extension extendee + 0, // [0:19] is the sub-list for field type_name +} + +func init() { file_substate_proto_init() } +func file_substate_proto_init() { + if File_substate_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_substate_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Substate); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_substate_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Substate_Account); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_substate_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Substate_AllocEntry); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_substate_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Substate_Alloc); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_substate_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Substate_BlockEnv); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_substate_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Substate_TxMessage); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_substate_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Substate_Result); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_substate_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Substate_Account_StorageEntry); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_substate_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Substate_BlockEnv_BlockHashEntry); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_substate_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Substate_TxMessage_AccessListEntry); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_substate_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Substate_Result_Log); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + file_substate_proto_msgTypes[1].OneofWrappers = []interface{}{ + (*Substate_Account_Code)(nil), + (*Substate_Account_CodeHash)(nil), + } + file_substate_proto_msgTypes[5].OneofWrappers = []interface{}{ + (*Substate_TxMessage_Data)(nil), + (*Substate_TxMessage_InitCodeHash)(nil), + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_substate_proto_rawDesc, + NumEnums: 1, + NumMessages: 11, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_substate_proto_goTypes, + DependencyIndexes: file_substate_proto_depIdxs, + EnumInfos: file_substate_proto_enumTypes, + MessageInfos: file_substate_proto_msgTypes, + }.Build() + File_substate_proto = out.File + file_substate_proto_rawDesc = nil + file_substate_proto_goTypes = nil + file_substate_proto_depIdxs = nil +} diff --git a/protobuf/substate.proto b/protobuf/substate.proto index 54efaa5..7453a5e 100644 --- a/protobuf/substate.proto +++ b/protobuf/substate.proto @@ -1,11 +1,11 @@ -yntax = "proto2"; -package research; +syntax = "proto2"; +package protobuf; // For a single optional bytes, use `optional BytesValue` // For an optional list of bytes, use `repeated bytes` import "google/protobuf/wrappers.proto"; -option go_package = "../research"; +option go_package = "../protobuf"; message Substate { diff --git a/protobuf/utils.go b/protobuf/utils.go new file mode 100644 index 0000000..f24a15b --- /dev/null +++ b/protobuf/utils.go @@ -0,0 +1,31 @@ +package protobuf + +import ( + "math/big" + + "github.com/Fantom-foundation/Substate/types" + wrapperspb "google.golang.org/protobuf/types/known/wrapperspb" +) + +func BytesValueToHash(bv *wrapperspb.BytesValue) *types.Hash { + if bv == nil { + return nil + } + hash := types.BytesToHash(bv.GetValue()) + return &hash +} + +func BytesValueToBigInt(bv *wrapperspb.BytesValue) *big.Int { + if bv == nil { + return nil + } + return new(big.Int).SetBytes(bv.GetValue()) +} + +func BytesValueToAddress(bv *wrapperspb.BytesValue) *types.Address { + if bv == nil { + return nil + } + addr := types.BytesToAddress(bv.GetValue()) + return &addr +} diff --git a/rlp/rlp_account.go b/rlp/rlp_account.go index 2ff254d..b65436f 100644 --- a/rlp/rlp_account.go +++ b/rlp/rlp_account.go @@ -11,7 +11,7 @@ import ( func NewRLPAccount(acc *substate.Account) *SubstateAccountRLP { a := &SubstateAccountRLP{ Nonce: acc.Nonce, - Balance: new(big.Int).Set(acc.Balance), + Balance: acc.Balance.ToBig(), CodeHash: acc.CodeHash(), Storage: [][2]types.Hash{}, } diff --git a/rlp/rlp_world_state.go b/rlp/rlp_world_state.go index a072010..f614ead 100644 --- a/rlp/rlp_world_state.go +++ b/rlp/rlp_world_state.go @@ -41,7 +41,11 @@ func (ws WorldState) ToSubstate(getHashFunc func(codeHash types.Hash) ([]byte, e if err != nil && !errors.Is(err, leveldb.ErrNotFound) { return nil, err } - sws[addr] = substate.NewAccount(acc.Nonce, acc.Balance, code) + sws[addr] = substate.NewAccount( + acc.Nonce, + types.BigIntToUint256(acc.Balance), + code, + ) for pos := range acc.Storage { sws[addr].Storage[acc.Storage[pos][0]] = acc.Storage[pos][1] } diff --git a/substate/account.go b/substate/account.go index 594c09f..0d8cbe1 100644 --- a/substate/account.go +++ b/substate/account.go @@ -3,22 +3,22 @@ package substate import ( "bytes" "fmt" - "math/big" "strings" "github.com/Fantom-foundation/Substate/types" "github.com/Fantom-foundation/Substate/types/hash" + "github.com/holiman/uint256" ) // Account holds any information about account used in a transaction. type Account struct { Nonce uint64 - Balance *big.Int + Balance *uint256.Int Storage map[types.Hash]types.Hash Code []byte } -func NewAccount(nonce uint64, balance *big.Int, code []byte) *Account { +func NewAccount(nonce uint64, balance *uint256.Int, code []byte) *Account { return &Account{ Nonce: nonce, Balance: balance, diff --git a/substate/env.go b/substate/env.go index 2b5ae6c..c705094 100644 --- a/substate/env.go +++ b/substate/env.go @@ -20,6 +20,8 @@ type Env struct { BaseFee *big.Int // nil if EIP-1559 is not activated // Cancun hard fork EIP-4844 BlobBaseFee *big.Int // nil if EIP-4844 is not activated + + Random *types.Hash } func NewEnv( diff --git a/substate/substate.go b/substate/substate.go index 85244bd..6a1fa7c 100644 --- a/substate/substate.go +++ b/substate/substate.go @@ -1,6 +1,7 @@ package substate import ( + "encoding/json" "errors" "fmt" "strings" @@ -79,3 +80,23 @@ func (s *Substate) String() string { return builder.String() } + +func (s *Substate) Dump(block uint64, tx int) error { + out := fmt.Sprintf("decoded block: %v Transaction: %v\n", block, tx) + + var jbytes []byte + jbytes, _ = json.MarshalIndent(s.InputSubstate, "", " ") + out += fmt.Sprintf("input:\n%s\n", jbytes) + jbytes, _ = json.MarshalIndent(s.Env, "", " ") + out += fmt.Sprintf("env:\n%s\n", jbytes) + jbytes, _ = json.MarshalIndent(s.Message, "", " ") + out += fmt.Sprintf("msg:\n%s\n", jbytes) + jbytes, _ = json.MarshalIndent(s.OutputSubstate, "", " ") + out += fmt.Sprintf("output:\n%s\n", jbytes) + jbytes, _ = json.MarshalIndent(s.Result, "", " ") + out += fmt.Sprintf("result:\n%s\n", jbytes) + + fmt.Println(out) + + return nil +} diff --git a/substate/world_state.go b/substate/world_state.go index beee654..c019378 100644 --- a/substate/world_state.go +++ b/substate/world_state.go @@ -3,10 +3,10 @@ package substate import ( "bytes" "fmt" - "math/big" "strings" "github.com/Fantom-foundation/Substate/types" + "github.com/holiman/uint256" ) const ( @@ -22,7 +22,7 @@ func NewWorldState() WorldState { type WorldState map[types.Address]*Account // Add assigns new Account to an Address -func (ws WorldState) Add(addr types.Address, nonce uint64, balance *big.Int, code []byte) WorldState { +func (ws WorldState) Add(addr types.Address, nonce uint64, balance *uint256.Int, code []byte) WorldState { ws[addr] = NewAccount(nonce, balance, code) return ws } @@ -37,7 +37,7 @@ func (ws WorldState) Merge(y WorldState) { // overwrite yAcc details in ws by y ws[yAddr].Nonce = yAcc.Nonce - ws[yAddr].Balance = new(big.Int).Set(yAcc.Balance) + ws[yAddr].Balance = yAcc.Balance ws[yAddr].Code = make([]byte, len(yAcc.Code)) copy(ws[yAddr].Code, yAcc.Code) } else { diff --git a/types/uint256.go b/types/uint256.go new file mode 100644 index 0000000..638a413 --- /dev/null +++ b/types/uint256.go @@ -0,0 +1,31 @@ +package types + +import ( + "math/big" + + "github.com/holiman/uint256" +) + +// BytesToUint256 strictly returns nil if b is nil +func BytesToUint256(b []byte) *uint256.Int { + if b == nil { + return nil + } + return new(uint256.Int).SetBytes(b) +} + +// BytesToBigInt strictly returns nil if b is nil +func BytesToBigInt(b []byte) *big.Int { + if b == nil { + return nil + } + return new(big.Int).SetBytes(b) +} + +// BigIntToUint256 strictly returns nil if big is nil +func BigIntToUint256(i *big.Int) *uint256.Int { + if i == nil { + return nil + } + return uint256.MustFromBig(i) +} diff --git a/updateset/update_set.go b/updateset/update_set.go index 36f0c3f..e882d67 100644 --- a/updateset/update_set.go +++ b/updateset/update_set.go @@ -63,7 +63,7 @@ func (up UpdateSetRLP) ToWorldState(getCodeFunc func(codeHash types.Hash) ([]byt acc := substate.Account{ Nonce: worldStateAcc.Nonce, - Balance: worldStateAcc.Balance, + Balance: types.BigIntToUint256(worldStateAcc.Balance), Storage: make(map[types.Hash]types.Hash), Code: code, } From d90279a7ebe0b011fc272b6d0eb4198f45065bad Mon Sep 17 00:00:00 2001 From: Rapol Date: Mon, 23 Sep 2024 14:01:10 +0200 Subject: [PATCH 03/27] revert extraneous line --- db/code_db.go | 1 - 1 file changed, 1 deletion(-) diff --git a/db/code_db.go b/db/code_db.go index 0fed13b..49755c3 100644 --- a/db/code_db.go +++ b/db/code_db.go @@ -88,7 +88,6 @@ func (db *codeDB) GetCode(codeHash types.Hash) ([]byte, error) { if err != nil { return nil, fmt.Errorf("cannot get code %s: %w", codeHash, err) } - return code, nil } From c052aa46f44c2a35f37f6f7996d7e8a3a8fe750d Mon Sep 17 00:00:00 2001 From: Rapol Date: Mon, 23 Sep 2024 14:03:05 +0200 Subject: [PATCH 04/27] remove extraneous comments + gofmt --- protobuf/decode.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/protobuf/decode.go b/protobuf/decode.go index 73116d7..6d7b7f4 100644 --- a/protobuf/decode.go +++ b/protobuf/decode.go @@ -166,7 +166,7 @@ func (msg *Substate_TxMessage) decode(lookup dbGetCode) (*substate.Message, erro // Berlin hard fork, EIP-2930: Optional access lists var accessList types.AccessList = nil // nil if EIP-2930 is not activated switch txType { - case Substate_TxMessage_TXTYPE_ACCESSLIST, + case Substate_TxMessage_TXTYPE_ACCESSLIST, Substate_TxMessage_TXTYPE_DYNAMICFEE, Substate_TxMessage_TXTYPE_BLOB: @@ -194,7 +194,7 @@ func (msg *Substate_TxMessage) decode(lookup dbGetCode) (*substate.Message, erro var gasFeeCap *big.Int = types.BytesToBigInt(msg.GetGasPrice()) var gasTipCap *big.Int = types.BytesToBigInt(msg.GetGasPrice()) switch txType { - case Substate_TxMessage_TXTYPE_DYNAMICFEE, + case Substate_TxMessage_TXTYPE_DYNAMICFEE, Substate_TxMessage_TXTYPE_BLOB: gasFeeCap = BytesValueToBigInt(msg.GetGasFeeCap()) From 91394cb516857e54208a42ca09ccd45b5081604d Mon Sep 17 00:00:00 2001 From: Rapol Date: Mon, 23 Sep 2024 14:11:55 +0200 Subject: [PATCH 05/27] revert uin256, to be separate PR --- rlp/rlp_account.go | 2 +- rlp/rlp_world_state.go | 6 +----- substate/account.go | 5 +++-- substate/world_state.go | 4 ++-- updateset/update_set.go | 2 +- 5 files changed, 8 insertions(+), 11 deletions(-) diff --git a/rlp/rlp_account.go b/rlp/rlp_account.go index b65436f..d590432 100644 --- a/rlp/rlp_account.go +++ b/rlp/rlp_account.go @@ -11,7 +11,7 @@ import ( func NewRLPAccount(acc *substate.Account) *SubstateAccountRLP { a := &SubstateAccountRLP{ Nonce: acc.Nonce, - Balance: acc.Balance.ToBig(), + Balance: Balance: new(big.Int).Set(acc.Balance), CodeHash: acc.CodeHash(), Storage: [][2]types.Hash{}, } diff --git a/rlp/rlp_world_state.go b/rlp/rlp_world_state.go index f614ead..a072010 100644 --- a/rlp/rlp_world_state.go +++ b/rlp/rlp_world_state.go @@ -41,11 +41,7 @@ func (ws WorldState) ToSubstate(getHashFunc func(codeHash types.Hash) ([]byte, e if err != nil && !errors.Is(err, leveldb.ErrNotFound) { return nil, err } - sws[addr] = substate.NewAccount( - acc.Nonce, - types.BigIntToUint256(acc.Balance), - code, - ) + sws[addr] = substate.NewAccount(acc.Nonce, acc.Balance, code) for pos := range acc.Storage { sws[addr].Storage[acc.Storage[pos][0]] = acc.Storage[pos][1] } diff --git a/substate/account.go b/substate/account.go index 0d8cbe1..d79530c 100644 --- a/substate/account.go +++ b/substate/account.go @@ -3,6 +3,7 @@ package substate import ( "bytes" "fmt" + "math/big" "strings" "github.com/Fantom-foundation/Substate/types" @@ -13,12 +14,12 @@ import ( // Account holds any information about account used in a transaction. type Account struct { Nonce uint64 - Balance *uint256.Int + Balance *big.Int Storage map[types.Hash]types.Hash Code []byte } -func NewAccount(nonce uint64, balance *uint256.Int, code []byte) *Account { +func NewAccount(nonce uint64, balance *big.Int, code []byte) *Account { return &Account{ Nonce: nonce, Balance: balance, diff --git a/substate/world_state.go b/substate/world_state.go index c019378..db16e96 100644 --- a/substate/world_state.go +++ b/substate/world_state.go @@ -3,10 +3,10 @@ package substate import ( "bytes" "fmt" + "math/big" "strings" "github.com/Fantom-foundation/Substate/types" - "github.com/holiman/uint256" ) const ( @@ -22,7 +22,7 @@ func NewWorldState() WorldState { type WorldState map[types.Address]*Account // Add assigns new Account to an Address -func (ws WorldState) Add(addr types.Address, nonce uint64, balance *uint256.Int, code []byte) WorldState { +func (ws WorldState) Add(addr types.Address, nonce uint64, balance *big.Int, code []byte) WorldState { ws[addr] = NewAccount(nonce, balance, code) return ws } diff --git a/updateset/update_set.go b/updateset/update_set.go index e882d67..36f0c3f 100644 --- a/updateset/update_set.go +++ b/updateset/update_set.go @@ -63,7 +63,7 @@ func (up UpdateSetRLP) ToWorldState(getCodeFunc func(codeHash types.Hash) ([]byt acc := substate.Account{ Nonce: worldStateAcc.Nonce, - Balance: types.BigIntToUint256(worldStateAcc.Balance), + Balance: worldStateAcc.Balance, Storage: make(map[types.Hash]types.Hash), Code: code, } From 2fe822277784dc1f03178f21865a2c9e125e59c1 Mon Sep 17 00:00:00 2001 From: Rapol Date: Mon, 23 Sep 2024 14:35:22 +0200 Subject: [PATCH 06/27] fix extraneous Balance --- rlp/rlp_account.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rlp/rlp_account.go b/rlp/rlp_account.go index d590432..2ff254d 100644 --- a/rlp/rlp_account.go +++ b/rlp/rlp_account.go @@ -11,7 +11,7 @@ import ( func NewRLPAccount(acc *substate.Account) *SubstateAccountRLP { a := &SubstateAccountRLP{ Nonce: acc.Nonce, - Balance: Balance: new(big.Int).Set(acc.Balance), + Balance: new(big.Int).Set(acc.Balance), CodeHash: acc.CodeHash(), Storage: [][2]types.Hash{}, } From 34165516196d1c193b92928a4e5fd380b676585e Mon Sep 17 00:00:00 2001 From: Rapol Date: Mon, 23 Sep 2024 14:42:51 +0200 Subject: [PATCH 07/27] remove extraneous uint256 --- substate/account.go | 1 - 1 file changed, 1 deletion(-) diff --git a/substate/account.go b/substate/account.go index d79530c..594c09f 100644 --- a/substate/account.go +++ b/substate/account.go @@ -8,7 +8,6 @@ import ( "github.com/Fantom-foundation/Substate/types" "github.com/Fantom-foundation/Substate/types/hash" - "github.com/holiman/uint256" ) // Account holds any information about account used in a transaction. From faeb1eb058ef279fa567a652a19d42825c03e4ff Mon Sep 17 00:00:00 2001 From: Rapol Date: Mon, 23 Sep 2024 14:47:10 +0200 Subject: [PATCH 08/27] decode reverts from uint256 to bigint --- protobuf/decode.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/protobuf/decode.go b/protobuf/decode.go index 6d7b7f4..708034f 100644 --- a/protobuf/decode.go +++ b/protobuf/decode.go @@ -92,9 +92,9 @@ func (entry *Substate_AllocEntry) decode() ([]byte, *Substate_Account, error) { return entry.GetAddress(), entry.GetAccount(), nil } -func (acct *Substate_Account) decode() (uint64, *uint256.Int, []byte, types.Hash, error) { +func (acct *Substate_Account) decode() (uint64, *big.Int, []byte, types.Hash, error) { return acct.GetNonce(), - types.BytesToUint256(acct.GetBalance()), + types.BytesToBigInt(acct.GetBalance()), acct.GetCode(), types.BytesToHash(acct.GetCodeHash()), nil From 64f8e8ede6baa20ce3ede7b42ef3419cdbadc5a8 Mon Sep 17 00:00:00 2001 From: Rapol Date: Mon, 23 Sep 2024 15:02:49 +0200 Subject: [PATCH 09/27] remove extranous uint256 import --- protobuf/decode.go | 1 - 1 file changed, 1 deletion(-) diff --git a/protobuf/decode.go b/protobuf/decode.go index 708034f..1b9677b 100644 --- a/protobuf/decode.go +++ b/protobuf/decode.go @@ -9,7 +9,6 @@ import ( "github.com/Fantom-foundation/Substate/types" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/crypto" - "github.com/holiman/uint256" "github.com/syndtr/goleveldb/leveldb" ) From 0f6a377d993d92c9ec0ee2fe5a751ff4aed638c6 Mon Sep 17 00:00:00 2001 From: RT <146690782+rpl-ffl@users.noreply.github.com> Date: Tue, 24 Sep 2024 18:35:31 +0700 Subject: [PATCH 10/27] Cleaner GetBlobHash clauses Co-authored-by: cabrador <84449820+cabrador@users.noreply.github.com> --- protobuf/decode.go | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/protobuf/decode.go b/protobuf/decode.go index 1b9677b..bf6e9c5 100644 --- a/protobuf/decode.go +++ b/protobuf/decode.go @@ -204,12 +204,14 @@ func (msg *Substate_TxMessage) decode(lookup dbGetCode) (*substate.Message, erro var blobHashes []types.Hash = nil switch txType { case Substate_TxMessage_TXTYPE_BLOB: - if msg.GetBlobHashes() != nil { - blobHashes = make([]types.Hash, len(msg.GetBlobHashes())) - for i, hash := range msg.GetBlobHashes() { - blobHashes[i] = types.BytesToHash(hash) - } - } + msgBlobHashes := msg.GetBlobHashes() + if msgBlobHashes == nil { + break + } + blobHashes = make([]types.Hash, len(msgBlobHashes)) + for i, hash := range msgBlobHashes { + blobHashes[i] = types.BytesToHash(hash) + } } return &substate.Message{ From e0d0de90ceb586e54a5566106c07ca8359875d4d Mon Sep 17 00:00:00 2001 From: Rapol Date: Wed, 25 Sep 2024 05:15:54 +0200 Subject: [PATCH 11/27] remove extraneous dangling error --- protobuf/decode.go | 94 ++++++++++++++++------------------------------ 1 file changed, 33 insertions(+), 61 deletions(-) diff --git a/protobuf/decode.go b/protobuf/decode.go index bf6e9c5..d14e0e1 100644 --- a/protobuf/decode.go +++ b/protobuf/decode.go @@ -26,10 +26,7 @@ func (s *Substate) Decode(lookup dbGetCode, block uint64, tx int) (*substate.Sub return nil, err } - environment, err := s.GetBlockEnv().decode() - if err != nil { - return nil, err - } + environment := s.GetBlockEnv().decode() message, err := s.GetTxMessage().decode(lookup) if err != nil { @@ -37,10 +34,7 @@ func (s *Substate) Decode(lookup dbGetCode, block uint64, tx int) (*substate.Sub } contractAddress := s.GetTxMessage().getContractAddress() - result, err := s.GetResult().decode(contractAddress) - if err != nil { - return nil, err - } + result := s.GetResult().decode(contractAddress) return &substate.Substate{ InputSubstate: *input, @@ -58,16 +52,9 @@ func (alloc *Substate_Alloc) decode(lookup dbGetCode) (*substate.WorldState, err world := make(substate.WorldState, len(alloc.GetAlloc())) for _, entry := range alloc.GetAlloc() { - addr, acct, err := entry.decode() - if err != nil { - return nil, fmt.Errorf("Error decoding alloc entry; %w", err) - } - + addr, acct := entry.decode() address := types.BytesToAddress(addr) - nonce, balance, _, codehash, err := acct.decode() - if err != nil { - return nil, fmt.Errorf("Error decoding entry account; %w", err) - } + nonce, balance, _, codehash := acct.decode() code, err := lookup(codehash) if err != nil && !errors.Is(err, leveldb.ErrNotFound) { @@ -76,10 +63,7 @@ func (alloc *Substate_Alloc) decode(lookup dbGetCode) (*substate.WorldState, err world[address] = substate.NewAccount(nonce, balance, code) for _, storage := range acct.GetStorage() { - key, value, err := storage.decode() - if err != nil { - return nil, fmt.Errorf("Error decoding account storage entry; %w", err) - } + key, value := storage.decode() world[address].Storage[key] = value } } @@ -87,34 +71,28 @@ func (alloc *Substate_Alloc) decode(lookup dbGetCode) (*substate.WorldState, err return &world, nil } -func (entry *Substate_AllocEntry) decode() ([]byte, *Substate_Account, error) { - return entry.GetAddress(), entry.GetAccount(), nil +func (entry *Substate_AllocEntry) decode() ([]byte, *Substate_Account) { + return entry.GetAddress(), entry.GetAccount() } -func (acct *Substate_Account) decode() (uint64, *big.Int, []byte, types.Hash, error) { +func (acct *Substate_Account) decode() (uint64, *big.Int, []byte, types.Hash) { return acct.GetNonce(), types.BytesToBigInt(acct.GetBalance()), acct.GetCode(), - types.BytesToHash(acct.GetCodeHash()), - nil + types.BytesToHash(acct.GetCodeHash()) } -func (entry *Substate_Account_StorageEntry) decode() (types.Hash, types.Hash, error) { - return types.BytesToHash(entry.GetKey()), - types.BytesToHash(entry.GetValue()), - nil +func (entry *Substate_Account_StorageEntry) decode() (types.Hash, types.Hash) { + return types.BytesToHash(entry.GetKey()), types.BytesToHash(entry.GetValue()) } // decode converts protobuf-encoded Substate_BlockEnv into aida-comprehensible Env -func (env *Substate_BlockEnv) decode() (*substate.Env, error) { +func (env *Substate_BlockEnv) decode() *substate.Env { var blockHashes map[uint64]types.Hash = nil if env.GetBlockHashes() != nil { blockHashes = make(map[uint64]types.Hash, len(env.GetBlockHashes())) for _, entry := range env.GetBlockHashes() { - key, value, err := entry.decode() - if err != nil { - return nil, err - } + key, value := entry.decode() blockHashes[key] = types.BytesToHash(value) } } @@ -129,11 +107,11 @@ func (env *Substate_BlockEnv) decode() (*substate.Env, error) { BaseFee: BytesValueToBigInt(env.GetBaseFee()), Random: BytesValueToHash(env.GetRandom()), BlobBaseFee: BytesValueToBigInt(env.GetBlobBaseFee()), - }, nil + } } -func (entry *Substate_BlockEnv_BlockHashEntry) decode() (uint64, []byte, error) { - return entry.GetKey(), entry.GetValue(), nil +func (entry *Substate_BlockEnv_BlockHashEntry) decode() (uint64, []byte) { + return entry.GetKey(), entry.GetValue() } // decode converts protobuf-encoded Substate_TxMessage into aida-comprehensible Message @@ -171,10 +149,7 @@ func (msg *Substate_TxMessage) decode(lookup dbGetCode) (*substate.Message, erro accessList = make([]types.AccessTuple, len(msg.GetAccessList())) for i, entry := range msg.GetAccessList() { - addr, keys, err := entry.decode() - if err != nil { - return nil, err - } + addr, keys := entry.decode() address := types.BytesToAddress(addr) storageKeys := make([]types.Hash, len(keys)) @@ -204,14 +179,15 @@ func (msg *Substate_TxMessage) decode(lookup dbGetCode) (*substate.Message, erro var blobHashes []types.Hash = nil switch txType { case Substate_TxMessage_TXTYPE_BLOB: - msgBlobHashes := msg.GetBlobHashes() - if msgBlobHashes == nil { - break - } - blobHashes = make([]types.Hash, len(msgBlobHashes)) - for i, hash := range msgBlobHashes { - blobHashes[i] = types.BytesToHash(hash) - } + msgBlobHashes := msg.GetBlobHashes() + if msgBlobHashes == nil { + break + } + + blobHashes = make([]types.Hash, len(msgBlobHashes)) + for i, hash := range msgBlobHashes { + blobHashes[i] = types.BytesToHash(hash) + } } return &substate.Message{ @@ -231,8 +207,8 @@ func (msg *Substate_TxMessage) decode(lookup dbGetCode) (*substate.Message, erro }, nil } -func (entry *Substate_TxMessage_AccessListEntry) decode() ([]byte, [][]byte, error) { - return entry.GetAddress(), entry.GetStorageKeys(), nil +func (entry *Substate_TxMessage_AccessListEntry) decode() ([]byte, [][]byte) { + return entry.GetAddress(), entry.GetStorageKeys() } // getContractAddress returns the address of the newly created contract if any. @@ -251,14 +227,10 @@ func (msg *Substate_TxMessage) getContractAddress() common.Address { } // decode converts protobuf-encoded Substate_Result into aida-comprehensible Result -func (res *Substate_Result) decode(contractAddress common.Address) (*substate.Result, error) { - var err error = nil +func (res *Substate_Result) decode(contractAddress common.Address) *substate.Result { logs := make([]*types.Log, len(res.GetLogs())) for i, log := range res.GetLogs() { - logs[i], err = log.decode() - if err != nil { - return nil, fmt.Errorf("Error decoding result; %w", err) - } + logs[i] = log.decode() } return substate.NewResult( @@ -267,10 +239,10 @@ func (res *Substate_Result) decode(contractAddress common.Address) (*substate.Re logs, // Logs types.BytesToAddress(contractAddress.Bytes()), // ContractAddress res.GetGasUsed(), // GasUsed - ), nil + ) } -func (log *Substate_Result_Log) decode() (*types.Log, error) { +func (log *Substate_Result_Log) decode() *types.Log { topics := make([]types.Hash, len(log.GetTopics())) for i, topic := range log.GetTopics() { topics[i] = types.BytesToHash(topic) @@ -280,5 +252,5 @@ func (log *Substate_Result_Log) decode() (*types.Log, error) { Address: types.BytesToAddress(log.GetAddress()), Topics: topics, Data: log.GetData(), - }, nil + } } From ced5262f98e5843a3d625ac34d9415106cba8c5d Mon Sep 17 00:00:00 2001 From: Rapol Date: Wed, 25 Sep 2024 05:28:52 +0200 Subject: [PATCH 12/27] cleaner explanation when look up initcodehash --- protobuf/decode.go | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/protobuf/decode.go b/protobuf/decode.go index d14e0e1..5a613b5 100644 --- a/protobuf/decode.go +++ b/protobuf/decode.go @@ -125,10 +125,8 @@ func (msg *Substate_TxMessage) decode(lookup dbGetCode) (*substate.Message, erro pTo = &address } - // if InitCodeHash exists: - // 1. code = lookup the code using InitCodeHash - // 2. set data -> code from (1) - // 3. clear InitCodeHash + // In normal cases, pass data directly. + // In case of contract creation, lookup msg.GetInitCodeHash() and pass that instead var data []byte = msg.GetData() if pTo == nil { code, err := lookup(types.BytesToHash(msg.GetInitCodeHash())) From 94a12f26a99eb350cea00996c678af3cc0a8a562 Mon Sep 17 00:00:00 2001 From: Rapol Date: Wed, 25 Sep 2024 05:41:31 +0200 Subject: [PATCH 13/27] explain random --- substate/env.go | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/substate/env.go b/substate/env.go index c705094..7f9c574 100644 --- a/substate/env.go +++ b/substate/env.go @@ -10,7 +10,6 @@ import ( type Env struct { Coinbase types.Address - Difficulty *big.Int GasLimit uint64 Number uint64 Timestamp uint64 @@ -20,8 +19,10 @@ type Env struct { BaseFee *big.Int // nil if EIP-1559 is not activated // Cancun hard fork EIP-4844 BlobBaseFee *big.Int // nil if EIP-4844 is not activated - - Random *types.Hash + + // EIP-4399: Supplant DIFFICULTY opcode with PREVRANDAO + Difficulty *big.Int // nil if EIP-4399 is activated + Random *types.Hash // nil if EIP-4399 is not activated } func NewEnv( From e655a885fc7cfb7f23fa9d90f5d92f14d330f109 Mon Sep 17 00:00:00 2001 From: Rapol Date: Wed, 25 Sep 2024 05:43:55 +0200 Subject: [PATCH 14/27] remove substate dump --- substate/substate.go | 20 -------------------- 1 file changed, 20 deletions(-) diff --git a/substate/substate.go b/substate/substate.go index 6a1fa7c..beea1ff 100644 --- a/substate/substate.go +++ b/substate/substate.go @@ -80,23 +80,3 @@ func (s *Substate) String() string { return builder.String() } - -func (s *Substate) Dump(block uint64, tx int) error { - out := fmt.Sprintf("decoded block: %v Transaction: %v\n", block, tx) - - var jbytes []byte - jbytes, _ = json.MarshalIndent(s.InputSubstate, "", " ") - out += fmt.Sprintf("input:\n%s\n", jbytes) - jbytes, _ = json.MarshalIndent(s.Env, "", " ") - out += fmt.Sprintf("env:\n%s\n", jbytes) - jbytes, _ = json.MarshalIndent(s.Message, "", " ") - out += fmt.Sprintf("msg:\n%s\n", jbytes) - jbytes, _ = json.MarshalIndent(s.OutputSubstate, "", " ") - out += fmt.Sprintf("output:\n%s\n", jbytes) - jbytes, _ = json.MarshalIndent(s.Result, "", " ") - out += fmt.Sprintf("result:\n%s\n", jbytes) - - fmt.Println(out) - - return nil -} From fc7756d33330a273cfb8bba2998e21be6ada8e06 Mon Sep 17 00:00:00 2001 From: Rapol Date: Wed, 25 Sep 2024 05:46:34 +0200 Subject: [PATCH 15/27] revert extraneous changes --- substate/world_state.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/substate/world_state.go b/substate/world_state.go index db16e96..beee654 100644 --- a/substate/world_state.go +++ b/substate/world_state.go @@ -37,7 +37,7 @@ func (ws WorldState) Merge(y WorldState) { // overwrite yAcc details in ws by y ws[yAddr].Nonce = yAcc.Nonce - ws[yAddr].Balance = yAcc.Balance + ws[yAddr].Balance = new(big.Int).Set(yAcc.Balance) ws[yAddr].Code = make([]byte, len(yAcc.Code)) copy(ws[yAddr].Code, yAcc.Code) } else { From bf429ad28add9c8b0d0db00336571e7f74ff0f6e Mon Sep 17 00:00:00 2001 From: Rapol Date: Thu, 26 Sep 2024 08:24:36 +0200 Subject: [PATCH 16/27] Add protobuf encoding test --- db/substate_db.go | 2 - db/substate_encoding.go | 21 ++++++ db/substate_encoding_test.go | 124 ++++++++++++++++++++++++++++------- go.mod | 23 ++++--- go.sum | 48 ++++++++++---- protobuf/decode.go | 4 +- substate/env.go | 6 +- substate/substate.go | 1 - 8 files changed, 176 insertions(+), 53 deletions(-) diff --git a/db/substate_db.go b/db/substate_db.go index 74bbe9f..904d8c1 100644 --- a/db/substate_db.go +++ b/db/substate_db.go @@ -4,11 +4,9 @@ import ( "encoding/binary" "fmt" - pb "github.com/Fantom-foundation/Substate/protobuf" "github.com/Fantom-foundation/Substate/rlp" "github.com/Fantom-foundation/Substate/substate" trlp "github.com/Fantom-foundation/Substate/types/rlp" - "github.com/golang/protobuf/proto" "github.com/syndtr/goleveldb/leveldb" "github.com/syndtr/goleveldb/leveldb/opt" "github.com/syndtr/goleveldb/leveldb/util" diff --git a/db/substate_encoding.go b/db/substate_encoding.go index 035dcc2..ed7675c 100644 --- a/db/substate_encoding.go +++ b/db/substate_encoding.go @@ -3,9 +3,11 @@ package db import ( "fmt" + pb "github.com/Fantom-foundation/Substate/protobuf" "github.com/Fantom-foundation/Substate/rlp" "github.com/Fantom-foundation/Substate/substate" "github.com/Fantom-foundation/Substate/types" + "github.com/golang/protobuf/proto" ) // SetSubstateEncoding sets the runtime encoding/decoding behavior of substateDB @@ -55,6 +57,14 @@ func newSubstateEncoding(encoding string, lookup codeLookup) (*substateEncoding, }, }, nil + case "protobuf", "pb": + return &substateEncoding{ + schema: "protobuf", + decode: func(bytes []byte, block uint64, tx int) (*substate.Substate, error) { + return decodeProtobuf(bytes, lookup, block, tx) + }, + }, nil + default: return nil, fmt.Errorf("Encoding not supported: %s", encoding) @@ -78,3 +88,14 @@ func decodeRlp(bytes []byte, lookup codeLookup, block uint64, tx int) (*substate return rlpSubstate.ToSubstate(lookup, block, tx) } + +// decodeProtobuf decodes into substate the provided rlp-encoded bytecode +func decodeProtobuf(bytes []byte, lookup codeLookup, block uint64, tx int) (*substate.Substate, error) { + pbSubstate := &pb.Substate{} + if err := proto.Unmarshal(bytes, pbSubstate); err != nil { + return nil, fmt.Errorf("cannot decode substate data from protobuf block: %v, tx %v; %w", block, tx, err) + } + + return pbSubstate.Decode(lookup, block, tx) +} + diff --git a/db/substate_encoding_test.go b/db/substate_encoding_test.go index 4bec5c3..3daaa89 100644 --- a/db/substate_encoding_test.go +++ b/db/substate_encoding_test.go @@ -3,18 +3,82 @@ package db import ( "strings" "testing" + "math/big" + "google.golang.org/protobuf/proto" + "google.golang.org/protobuf/types/known/wrapperspb" + pb "github.com/Fantom-foundation/Substate/protobuf" "github.com/Fantom-foundation/Substate/rlp" trlp "github.com/Fantom-foundation/Substate/types/rlp" ) +type encTest struct { + bytes []byte + blk uint64 + tx int +} + var ( - testRlp, _ = trlp.EncodeToBytes(rlp.NewRLP(testSubstate)) - testBlk = testSubstate.Block - testTx = testSubstate.Transaction + o uint64 = 1 + one *uint64 = &o + bigOne *big.Int = new(big.Int).SetUint64(1) + typeOne = pb.Substate_TxMessage_TXTYPE_LEGACY +) + +var testPbSubstate = &pb.Substate{ + InputAlloc: &pb.Substate_Alloc{}, + OutputAlloc: &pb.Substate_Alloc{}, + BlockEnv: &pb.Substate_BlockEnv{ + Coinbase: []byte{1}, + Difficulty: []byte{1}, + GasLimit: one, + Number: one, + Timestamp: one, + BaseFee: wrapperspb.Bytes([]byte{1}), + }, + TxMessage: &pb.Substate_TxMessage{ + Nonce: one, + GasPrice: []byte{1}, + Gas: one, + From: []byte{1}, + To: nil, + Value: []byte{1}, + Input: &pb.Substate_TxMessage_InitCodeHash{ + InitCodeHash: []byte{1}, + }, + TxType: &typeOne, + AccessList: []*pb.Substate_TxMessage_AccessListEntry{}, + GasFeeCap: wrapperspb.Bytes([]byte{1}), + GasTipCap: wrapperspb.Bytes([]byte{1}), + BlobGasFeeCap: wrapperspb.Bytes([]byte{1}), + BlobHashes: [][]byte{}, + }, + Result: &pb.Substate_Result{ + Status: one, + Bloom: []byte{1}, + Logs: []*pb.Substate_Result_Log{}, + GasUsed: one, + }, +} - supportedEncoding = map[string][]byte{ +var ( + simplePb, _ = proto.Marshal(testPbSubstate) + testPb = encTest { + bytes: simplePb, + blk: testSubstate.Block, + tx: testSubstate.Transaction, + } + + simpleRlp, _ = trlp.EncodeToBytes(rlp.NewRLP(testSubstate)) + testRlp = encTest{ + bytes: simpleRlp, + blk: testSubstate.Block, + tx: testSubstate.Transaction, + } + + supportedEncoding = map[string]encTest{ "rlp": testRlp, + "protobuf": testPb, } ) @@ -30,7 +94,7 @@ func TestSubstateEncoding_NilEncodingDefaultsToRlp(t *testing.T) { } // purposely never set encoding - _, err = db.decodeToSubstate(testRlp, testBlk, testTx) + _, err = db.decodeToSubstate(testRlp.bytes, testRlp.blk, testRlp.tx) if err != nil { t.Fatal(err) } @@ -52,7 +116,7 @@ func TestSubstateEncoding_DefaultEncodingDefaultsToRlp(t *testing.T) { t.Fatal("default is supportet, but error") } - _, err = db.decodeToSubstate(testRlp, testBlk, testTx) + _, err = db.decodeToSubstate(testRlp.bytes, testRlp.blk, testRlp.tx) if err != nil { t.Fatal(err) } @@ -75,52 +139,66 @@ func TestSubstateEncoding_UnsupportedEncodingThrowsError(t *testing.T) { } } -func TestSubstateEncoding_TestDb(t *testing.T) { - path := t.TempDir() + "test-db" - db, err := newSubstateDB(path, nil, nil, nil) +func TestSubstateEncoding_EncodePb(t *testing.T) { + ss, err := proto.Marshal(testPbSubstate) if err != nil { - t.Errorf("cannot open db; %v", err) + t.Fatal(err) } - for encoding, bytes := range supportedEncoding { - _, err = db.SetSubstateEncoding(encoding) + pbSubstate := &pb.Substate{} + if err := proto.Unmarshal(ss, pbSubstate); err != nil { + t.Fatal(err) + } +} + + +func TestSubstateEncoding_TestDb(t *testing.T) { + for encoding, et := range supportedEncoding { + path := t.TempDir() + "test-db-" + encoding + db, err := newSubstateDB(path, nil, nil, nil) if err != nil { - t.Error(err) + t.Errorf("cannot open db; %v", err) } - ss, err := db.decodeToSubstate(bytes, testBlk, testTx) + db, err = db.SetSubstateEncoding(encoding) if err != nil { t.Error(err) } - err = addCustomSubstate(db, testBlk, ss) + ss, err := db.decodeToSubstate(et.bytes, et.blk, et.tx) if err != nil { t.Error(err) } + err = addCustomSubstate(db, et.blk, ss) + if err != nil { + t.Error(err) + } + testSubstateDB_GetSubstate(db, t) } } func TestSubstateEncoding_TestIterator(t *testing.T) { - path := t.TempDir() + "test-db" - db, err := newSubstateDB(path, nil, nil, nil) - if err != nil { - t.Errorf("cannot open db; %v", err) - } + for encoding, et := range supportedEncoding { + path := t.TempDir() + "test-db-" + encoding + db, err := newSubstateDB(path, nil, nil, nil) + if err != nil { + t.Errorf("cannot open db; %v", err) + } - for encoding, bytes := range supportedEncoding { + fmt.Println(encoding) _, err = db.SetSubstateEncoding(encoding) if err != nil { t.Error(err) } - ss, err := db.decodeToSubstate(bytes, testBlk, testTx) + ss, err := db.decodeToSubstate(et.bytes, et.blk, et.tx) if err != nil { t.Error(err) } - err = addCustomSubstate(db, testBlk, ss) + err = addCustomSubstate(db, et.blk, ss) if err != nil { t.Error(err) } diff --git a/go.mod b/go.mod index 60d0c28..9f318f2 100644 --- a/go.mod +++ b/go.mod @@ -1,22 +1,29 @@ module github.com/Fantom-foundation/Substate -go 1.21 +go 1.22 + +toolchain go1.22.4 require ( - github.com/syndtr/goleveldb v1.0.1-0.20210305035536-64b5b1c73954 - github.com/urfave/cli/v2 v2.24.4 - golang.org/x/crypto v0.17.0 + github.com/ethereum/go-ethereum v1.14.9 + github.com/golang/protobuf v1.5.4 + github.com/holiman/uint256 v1.3.1 + github.com/stretchr/testify v1.9.0 + github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 + github.com/urfave/cli/v2 v2.25.7 + golang.org/x/crypto v0.22.0 + google.golang.org/protobuf v1.34.2 ) require ( + github.com/btcsuite/btcd/btcec/v2 v2.3.4 // indirect github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect github.com/davecgh/go-spew v1.1.1 // indirect - github.com/golang/snappy v0.0.3 // indirect + github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 // indirect + github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect - github.com/stretchr/testify v1.9.0 // indirect github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect - golang.org/x/sys v0.15.0 // indirect - gopkg.in/yaml.v2 v2.4.0 // indirect + golang.org/x/sys v0.22.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index bd658ba..22155db 100644 --- a/go.sum +++ b/go.sum @@ -1,10 +1,21 @@ +github.com/btcsuite/btcd/btcec/v2 v2.3.4 h1:3EJjcN70HCu/mwqlUsGK8GcNVyLVxFDlWurTXGPFfiQ= +github.com/btcsuite/btcd/btcec/v2 v2.3.4/go.mod h1:zYzJ8etWJQIv1Ogk7OzpWjowwOdXY1W/17j2MW85J04= +github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1 h1:q0rUy8C/TYNBQS1+CGKw68tLOFYSNEs0TFnxxnS9+4U= +github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1/go.mod h1:7SFka0XMvUgj3hfZtydOrQY2mwhPclbT2snogU7SQQc= github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w= github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/decred/dcrd/crypto/blake256 v1.0.0 h1:/8DMNYp9SGi5f0w7uCm6d6M4OU2rGFK09Y2A4Xv7EE0= +github.com/decred/dcrd/crypto/blake256 v1.0.0/go.mod h1:sQl2p6Y26YV+ZOcSTP6thNdn47hh8kt6rqSlvmrXFAc= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 h1:YLtO71vCjJRCBcrPMtQ9nqBsqpA1m5sE92cU+pd5Mcc= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1/go.mod h1:hyedUtir6IdtD/7lIxGeCxkaw7y45JueMRL4DIyJDKs= +github.com/ethereum/go-ethereum v1.14.9 h1:J7iwXDrtUyE9FUjUYbd4c9tyzwMh6dTJsKzo9i6SrwA= +github.com/ethereum/go-ethereum v1.14.9/go.mod h1:QeW+MtTpRdBEm2pUFoonByee8zfHv7kGp0wK0odvU1I= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= -github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= +github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= +github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= @@ -12,12 +23,18 @@ github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrU github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= -github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/golang/snappy v0.0.3 h1:fHPg5GQYlCeLIPB9BZqMVR5nR9A+IM5zcgeTdjMYmLA= -github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= +github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= +github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb h1:PBC98N2aIaM3XXiurYmW7fx4GZkL8feAMVq7nEjURHk= +github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/holiman/uint256 v1.3.1 h1:JfTzmih28bittyHM8z360dCjIA9dbPIBlcTI6lmctQs= +github.com/holiman/uint256 v1.3.1/go.mod h1:EOMSn4q6Nyt9P6efbI3bueV4e1b3dGlUCXeiRV4ng7E= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= @@ -34,22 +51,22 @@ github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= -github.com/syndtr/goleveldb v1.0.1-0.20210305035536-64b5b1c73954 h1:xQdMZ1WLrgkkvOZ/LDQxjVxMLdby7osSh4ZEVa5sIjs= -github.com/syndtr/goleveldb v1.0.1-0.20210305035536-64b5b1c73954/go.mod h1:u2MKkTVTVJWe5D1rCvame8WqhBd88EuIwODJZ1VHCPM= -github.com/urfave/cli/v2 v2.24.4 h1:0gyJJEBYtCV87zI/x2nZCPyDxD51K6xM8SkwjHFCNEU= -github.com/urfave/cli/v2 v2.24.4/go.mod h1:GHupkWPMM0M/sj1a2b4wUrWBPzazNrIjouW6fmdJLxc= +github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 h1:epCh84lMvA70Z7CTTCmYQn2CKbY8j86K7/FAIr141uY= +github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7/go.mod h1:q4W45IWZaF22tdD+VEXcAWRA037jwmWEB5VWYORlTpc= +github.com/urfave/cli/v2 v2.25.7 h1:VAzn5oq403l5pHjc4OhD54+XGO9cdKVL/7lDjF+iKUs= +github.com/urfave/cli/v2 v2.25.7/go.mod h1:8qnjx1vcq5s2/wpsqoZFndg2CE5tNFyrTvS6SinrnYQ= github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU= github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.17.0 h1:r8bRNjWL3GshPW3gkd+RpvzWrZAwPS49OmTGZ/uhM4k= -golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= +golang.org/x/crypto v0.22.0 h1:g1v0xeRhjcugydODzvb3mEM9SQ0HGp9s/nh3COQ/C30= +golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200813134508-3edf25e44fcc/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M= -golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= +golang.org/x/net v0.24.0 h1:1PcaxkF854Fu3+lvBIx5SYn9wRlBzzcnHZSiaFFAb0w= +golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -60,8 +77,8 @@ golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200814200057-3d37ad5750ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc= -golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= +golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= @@ -77,6 +94,9 @@ google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQ google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= +google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= diff --git a/protobuf/decode.go b/protobuf/decode.go index 5a613b5..e56ee3d 100644 --- a/protobuf/decode.go +++ b/protobuf/decode.go @@ -5,10 +5,10 @@ import ( "fmt" "math/big" - "github.com/Fantom-foundation/Substate/substate" - "github.com/Fantom-foundation/Substate/types" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/crypto" + "github.com/Fantom-foundation/Substate/substate" + "github.com/Fantom-foundation/Substate/types" "github.com/syndtr/goleveldb/leveldb" ) diff --git a/substate/env.go b/substate/env.go index 7f9c574..d7776a8 100644 --- a/substate/env.go +++ b/substate/env.go @@ -19,10 +19,10 @@ type Env struct { BaseFee *big.Int // nil if EIP-1559 is not activated // Cancun hard fork EIP-4844 BlobBaseFee *big.Int // nil if EIP-4844 is not activated - + // EIP-4399: Supplant DIFFICULTY opcode with PREVRANDAO - Difficulty *big.Int // nil if EIP-4399 is activated - Random *types.Hash // nil if EIP-4399 is not activated + Difficulty *big.Int // nil if EIP-4399 is activated + Random *types.Hash // nil if EIP-4399 is not activated } func NewEnv( diff --git a/substate/substate.go b/substate/substate.go index beea1ff..85244bd 100644 --- a/substate/substate.go +++ b/substate/substate.go @@ -1,7 +1,6 @@ package substate import ( - "encoding/json" "errors" "fmt" "strings" From 32ce417507714f5da37c5772db673225b9a3fdb8 Mon Sep 17 00:00:00 2001 From: Rapol Date: Fri, 27 Sep 2024 13:18:27 +0200 Subject: [PATCH 17/27] encoding now works --- db/substate_db.go | 7 +- db/substate_db_test.go | 2 +- db/substate_encoding.go | 38 ++++++++- db/substate_encoding_test.go | 94 +++++----------------- protobuf/encode.go | 147 +++++++++++++++++++++++++++++++++++ substate/message.go | 1 + types/address.go | 10 +++ types/hash.go | 10 +++ types/uint256.go | 31 -------- types/utils.go | 40 ++++++++++ 10 files changed, 267 insertions(+), 113 deletions(-) create mode 100644 protobuf/encode.go delete mode 100644 types/uint256.go create mode 100644 types/utils.go diff --git a/db/substate_db.go b/db/substate_db.go index 904d8c1..38601f1 100644 --- a/db/substate_db.go +++ b/db/substate_db.go @@ -4,9 +4,7 @@ import ( "encoding/binary" "fmt" - "github.com/Fantom-foundation/Substate/rlp" "github.com/Fantom-foundation/Substate/substate" - trlp "github.com/Fantom-foundation/Substate/types/rlp" "github.com/syndtr/goleveldb/leveldb" "github.com/syndtr/goleveldb/leveldb/opt" "github.com/syndtr/goleveldb/leveldb/util" @@ -180,10 +178,9 @@ func (db *substateDB) PutSubstate(ss *substate.Substate) error { key := SubstateDBKey(ss.Block, ss.Transaction) - substateRLP := rlp.NewRLP(ss) - value, err := trlp.EncodeToBytes(substateRLP) + value, err := db.encodeSubstate(ss, ss.Block, ss.Transaction) if err != nil { - return fmt.Errorf("cannot encode substate-rlp block %v, tx %v; %v", ss.Block, ss.Transaction, err) + return fmt.Errorf("cannot encode substate block %v, tx %v; %v", ss.Block, ss.Transaction, err) } return db.Put(key, value) diff --git a/db/substate_db_test.go b/db/substate_db_test.go index a3f1105..ac5cca2 100644 --- a/db/substate_db_test.go +++ b/db/substate_db_test.go @@ -24,7 +24,7 @@ var testSubstate = &substate.Substate{ BaseFee: new(big.Int).SetUint64(1), }, Message: substate.NewMessage(1, true, new(big.Int).SetUint64(1), 1, types.Address{1}, new(types.Address), new(big.Int).SetUint64(1), []byte{1}, nil, types.AccessList{}, new(big.Int).SetUint64(1), new(big.Int).SetUint64(1), new(big.Int).SetUint64(1), make([]types.Hash, 0)), - Result: substate.NewResult(1, types.Bloom{}, []*types.Log{}, types.Address{1}, 1), + Result: substate.NewResult(1, types.Bloom{}, []*types.Log{}, types.Address{}, 1), Block: 37_534_834, Transaction: 1, } diff --git a/db/substate_encoding.go b/db/substate_encoding.go index ed7675c..c0e7815 100644 --- a/db/substate_encoding.go +++ b/db/substate_encoding.go @@ -7,6 +7,7 @@ import ( "github.com/Fantom-foundation/Substate/rlp" "github.com/Fantom-foundation/Substate/substate" "github.com/Fantom-foundation/Substate/types" + trlp "github.com/Fantom-foundation/Substate/types/rlp" "github.com/golang/protobuf/proto" ) @@ -37,11 +38,15 @@ func (db *substateDB) GetSubstateEncoding() string { type substateEncoding struct { schema string decode decoderFunc + encode encodeFunc } // decoderFunc aliases the common function used to decode substate type decoderFunc func([]byte, uint64, int) (*substate.Substate, error) +// encodeFunc alias the common function used to encode substate +type encodeFunc func(*substate.Substate, uint64, int) ([]byte, error) + // codeLookup aliases codehash->code lookup necessary to decode substate type codeLookup = func(types.Hash) ([]byte, error) @@ -49,12 +54,13 @@ type codeLookup = func(types.Hash) ([]byte, error) func newSubstateEncoding(encoding string, lookup codeLookup) (*substateEncoding, error) { switch encoding { - case "default", "rlp": + case "", "default", "rlp": return &substateEncoding{ schema: "rlp", decode: func(bytes []byte, block uint64, tx int) (*substate.Substate, error) { return decodeRlp(bytes, lookup, block, tx) }, + encode: encodeRlp, }, nil case "protobuf", "pb": @@ -63,6 +69,7 @@ func newSubstateEncoding(encoding string, lookup codeLookup) (*substateEncoding, decode: func(bytes []byte, block uint64, tx int) (*substate.Substate, error) { return decodeProtobuf(bytes, lookup, block, tx) }, + encode: encodeProtobuf, }, nil default: @@ -79,6 +86,15 @@ func (db *substateDB) decodeToSubstate(bytes []byte, block uint64, tx int) (*sub return db.encoding.decode(bytes, block, tx) } +// encodeSubstate defensively defaults to "default" if nil +func (db *substateDB) encodeSubstate(ss *substate.Substate, block uint64, tx int) ([]byte, error) { + if db.encoding == nil { + db.SetSubstateEncoding("default") + } + return db.encoding.encode(ss, block, tx) +} + + // decodeRlp decodes into substate the provided rlp-encoded bytecode func decodeRlp(bytes []byte, lookup codeLookup, block uint64, tx int) (*substate.Substate, error) { rlpSubstate, err := rlp.Decode(bytes) @@ -89,6 +105,16 @@ func decodeRlp(bytes []byte, lookup codeLookup, block uint64, tx int) (*substate return rlpSubstate.ToSubstate(lookup, block, tx) } +//encodeRlp encodes into rlp-encoded bytes the provided substate +func encodeRlp(ss *substate.Substate, block uint64, tx int) ([]byte, error) { + bytes, err := trlp.EncodeToBytes(rlp.NewRLP(ss)) + if err != nil { + return nil, fmt.Errorf("cannot encode substate into rlp block: %v, tx %v; %w", block, tx, err) + } + + return bytes, nil +} + // decodeProtobuf decodes into substate the provided rlp-encoded bytecode func decodeProtobuf(bytes []byte, lookup codeLookup, block uint64, tx int) (*substate.Substate, error) { pbSubstate := &pb.Substate{} @@ -99,3 +125,13 @@ func decodeProtobuf(bytes []byte, lookup codeLookup, block uint64, tx int) (*sub return pbSubstate.Decode(lookup, block, tx) } +//encodeRlp encodes into rlp-encoded bytes the provided substate +func encodeProtobuf(ss *substate.Substate, block uint64, tx int) ([]byte, error) { + bytes, err := proto.Marshal(pb.Encode(ss)) + if err != nil { + return nil, fmt.Errorf("cannot encode substate into protobuf block: %v, tx %v; %w", block, tx, err) + } + + return bytes, nil +} + diff --git a/db/substate_encoding_test.go b/db/substate_encoding_test.go index 3daaa89..39620ca 100644 --- a/db/substate_encoding_test.go +++ b/db/substate_encoding_test.go @@ -3,10 +3,8 @@ package db import ( "strings" "testing" - "math/big" "google.golang.org/protobuf/proto" - "google.golang.org/protobuf/types/known/wrapperspb" pb "github.com/Fantom-foundation/Substate/protobuf" "github.com/Fantom-foundation/Substate/rlp" trlp "github.com/Fantom-foundation/Substate/types/rlp" @@ -19,50 +17,7 @@ type encTest struct { } var ( - o uint64 = 1 - one *uint64 = &o - bigOne *big.Int = new(big.Int).SetUint64(1) - typeOne = pb.Substate_TxMessage_TXTYPE_LEGACY -) - -var testPbSubstate = &pb.Substate{ - InputAlloc: &pb.Substate_Alloc{}, - OutputAlloc: &pb.Substate_Alloc{}, - BlockEnv: &pb.Substate_BlockEnv{ - Coinbase: []byte{1}, - Difficulty: []byte{1}, - GasLimit: one, - Number: one, - Timestamp: one, - BaseFee: wrapperspb.Bytes([]byte{1}), - }, - TxMessage: &pb.Substate_TxMessage{ - Nonce: one, - GasPrice: []byte{1}, - Gas: one, - From: []byte{1}, - To: nil, - Value: []byte{1}, - Input: &pb.Substate_TxMessage_InitCodeHash{ - InitCodeHash: []byte{1}, - }, - TxType: &typeOne, - AccessList: []*pb.Substate_TxMessage_AccessListEntry{}, - GasFeeCap: wrapperspb.Bytes([]byte{1}), - GasTipCap: wrapperspb.Bytes([]byte{1}), - BlobGasFeeCap: wrapperspb.Bytes([]byte{1}), - BlobHashes: [][]byte{}, - }, - Result: &pb.Substate_Result{ - Status: one, - Bloom: []byte{1}, - Logs: []*pb.Substate_Result_Log{}, - GasUsed: one, - }, -} - -var ( - simplePb, _ = proto.Marshal(testPbSubstate) + simplePb, _ = proto.Marshal(pb.Encode(testSubstate)) testPb = encTest { bytes: simplePb, blk: testSubstate.Block, @@ -105,24 +60,27 @@ func TestSubstateEncoding_NilEncodingDefaultsToRlp(t *testing.T) { } func TestSubstateEncoding_DefaultEncodingDefaultsToRlp(t *testing.T) { - path := t.TempDir() + "test-db" - db, err := newSubstateDB(path, nil, nil, nil) - if err != nil { - t.Errorf("cannot open db; %v", err) - } + defaultKeywords := []string{"", "default"} + for _, defaultEncoding := range defaultKeywords { + path := t.TempDir() + "test-db-" + defaultEncoding + db, err := newSubstateDB(path, nil, nil, nil) + if err != nil { + t.Errorf("cannot open db; %v", err) + } - _, err = db.SetSubstateEncoding("default") - if err != nil { - t.Fatal("default is supportet, but error") - } + _, err = db.SetSubstateEncoding(defaultEncoding) + if err != nil { + t.Fatalf("Default encoding '%s' must be supported, but error", defaultEncoding) + } - _, err = db.decodeToSubstate(testRlp.bytes, testRlp.blk, testRlp.tx) - if err != nil { - t.Fatal(err) - } + _, err = db.decodeToSubstate(testRlp.bytes, testRlp.blk, testRlp.tx) + if err != nil { + t.Fatal(err) + } - if got := db.GetSubstateEncoding(); got != "rlp" { - t.Fatalf("db should default to rlp, got: %s", got) + if got := db.GetSubstateEncoding(); got != "rlp" { + t.Fatalf("db should default to rlp, got: %s", got) + } } } @@ -139,19 +97,6 @@ func TestSubstateEncoding_UnsupportedEncodingThrowsError(t *testing.T) { } } -func TestSubstateEncoding_EncodePb(t *testing.T) { - ss, err := proto.Marshal(testPbSubstate) - if err != nil { - t.Fatal(err) - } - - pbSubstate := &pb.Substate{} - if err := proto.Unmarshal(ss, pbSubstate); err != nil { - t.Fatal(err) - } -} - - func TestSubstateEncoding_TestDb(t *testing.T) { for encoding, et := range supportedEncoding { path := t.TempDir() + "test-db-" + encoding @@ -187,7 +132,6 @@ func TestSubstateEncoding_TestIterator(t *testing.T) { t.Errorf("cannot open db; %v", err) } - fmt.Println(encoding) _, err = db.SetSubstateEncoding(encoding) if err != nil { t.Error(err) diff --git a/protobuf/encode.go b/protobuf/encode.go new file mode 100644 index 0000000..874b152 --- /dev/null +++ b/protobuf/encode.go @@ -0,0 +1,147 @@ +package protobuf + +import ( + "github.com/Fantom-foundation/Substate/substate" + "github.com/Fantom-foundation/Substate/types" + "github.com/Fantom-foundation/Substate/types/hash" +) + +// Encode converts aida-substate into protobuf-encoded message +func Encode(ss *substate.Substate) *Substate { + return &Substate{ + InputAlloc: encodeWorldState(ss.InputSubstate), + OutputAlloc: encodeWorldState(ss.OutputSubstate), + BlockEnv: encodeEnv(ss.Env), + TxMessage: encodeMessage(ss.Message), + Result: encodeResult(ss.Result), + } +} + +// encodeWorldState converts substate.WorldState into protobuf-encoded Substate_Alloc +func encodeWorldState(sw substate.WorldState) *Substate_Alloc { + world := make([]*Substate_AllocEntry, 0, len(sw)) + for addr, acct := range sw { + storage := make([]*Substate_Account_StorageEntry, 0, len(acct.Storage)) + for key, value := range acct.Storage { + storage = append(storage, &Substate_Account_StorageEntry{ + Key: key.Bytes(), + Value: value.Bytes(), + }) + } + + world = append(world, &Substate_AllocEntry { + Address: addr.Bytes(), + Account: &Substate_Account{ + Nonce: &acct.Nonce, + Balance: acct.Balance.Bytes(), + Storage: storage, + Contract: &Substate_Account_CodeHash{ + CodeHash: hash.Keccak256Hash(acct.Code).Bytes(), + }, + }, + }) + } + + return &Substate_Alloc{Alloc: world} +} + +// encode converts substate.Env into protobuf-encoded Substate_BlockEnv +func encodeEnv(se *substate.Env) *Substate_BlockEnv { + blockHashes := make([]*Substate_BlockEnv_BlockHashEntry, 0, len(se.BlockHashes)) + for number, hash := range se.BlockHashes { + blockHashes = append(blockHashes, &Substate_BlockEnv_BlockHashEntry{ + Key: &number, + Value: hash.Bytes(), + }) + } + + return &Substate_BlockEnv{ + Coinbase: se.Coinbase.Bytes(), + Difficulty: se.Difficulty.Bytes(), + GasLimit: &se.GasLimit, + Number: &se.Number, + Timestamp: &se.Timestamp, + BlockHashes: blockHashes, + BaseFee: types.BigIntToWrapperspbBytes(se.BaseFee), + BlobBaseFee: types.BigIntToWrapperspbBytes(se.BlobBaseFee), + Random: types.HashToWrapperspbBytes(se.Random), + } +} + +// encode converts substate.Message into protobuf-encoded Substate_TxMessage +func encodeMessage(sm *substate.Message) *Substate_TxMessage { + dt := Substate_TxMessage_TXTYPE_LEGACY + txType := &dt + if sm.ProtobufTxType != nil { + t := Substate_TxMessage_TxType(*sm.ProtobufTxType) + txType = &t + } + + accessList := make([]*Substate_TxMessage_AccessListEntry, len(sm.AccessList)) + for i, entry := range sm.AccessList { + accessList[i].encode(&entry) + } + + blobHashes := make([][]byte, len(sm.BlobHashes)) + for i, hash := range sm.BlobHashes { + blobHashes[i] = hash.Bytes() + } + + return &Substate_TxMessage{ + Nonce: &sm.Nonce, + GasPrice: sm.GasPrice.Bytes(), + Gas: &sm.Gas, + From: sm.From.Bytes(), + To: types.AddressToWrapperspbBytes(sm.To), + Value: sm.Value.Bytes(), + Input: &Substate_TxMessage_Data{Data: sm.Data}, + TxType: txType, + AccessList: accessList, + GasFeeCap: types.BigIntToWrapperspbBytes(sm.GasFeeCap), + GasTipCap: types.BigIntToWrapperspbBytes(sm.GasTipCap), + BlobGasFeeCap: types.BigIntToWrapperspbBytes(sm.BlobGasFeeCap), + BlobHashes: blobHashes, + } +} + +// encode converts types.AccessTuple into protobuf-encoded Substate_TxMessage_AccessListEntry +func (entry *Substate_TxMessage_AccessListEntry) encode(sat *types.AccessTuple) { + keys := make([][]byte, len(sat.StorageKeys)) + for i, key := range sat.StorageKeys { + keys[i] = key.Bytes() + } + + entry = &Substate_TxMessage_AccessListEntry{ + Address: sat.Address.Bytes(), + StorageKeys: keys, + } +} + +// encode converts substate.Results into protobuf-encoded Substate_Result +func encodeResult(sr *substate.Result) *Substate_Result { + logs := make([]*Substate_Result_Log, len(sr.Logs)) + for i, log := range sr.Logs { + logs[i].encode(log) + } + + return &Substate_Result { + Status: &sr.Status, + Bloom: sr.Bloom.Bytes(), + Logs: logs, + GasUsed: &sr.GasUsed, + } +} + +// encode converts types.Log into protobuf-encoded Substate_Result_log +func (log *Substate_Result_Log) encode(sl *types.Log) { + topics := make([][]byte, len(sl.Topics)) + for i, topic := range sl.Topics { + topics[i] = topic.Bytes() + } + + log = &Substate_Result_Log { + Address: sl.Address.Bytes(), + Topics: topics, + Data: sl.Data, + } +} diff --git a/substate/message.go b/substate/message.go index f2549c6..4fee0a4 100644 --- a/substate/message.go +++ b/substate/message.go @@ -24,6 +24,7 @@ type Message struct { // for memoization dataHash *types.Hash + ProtobufTxType *int32 // when encoding pbuf // Berlin hard fork, EIP-2930: Optional access lists AccessList types.AccessList // nil if EIP-2930 is not activated diff --git a/types/address.go b/types/address.go index ed2b7f8..38fb144 100644 --- a/types/address.go +++ b/types/address.go @@ -2,6 +2,8 @@ package types import ( "encoding/hex" + + "google.golang.org/protobuf/types/known/wrapperspb" ) const AddressLength = 20 @@ -73,3 +75,11 @@ func (a *Address) UnmarshalText(text []byte) error { *a = BytesToAddress(FromHex(string(text))) return nil } + +// AddressToWrapperspbBytes returns address as wrapperspb.BytesValue, nil if address is nil +func AddressToWrapperspbBytes(a *Address) *wrapperspb.BytesValue { + if a == nil { + return nil + } + return wrapperspb.Bytes(a.Bytes()) +} diff --git a/types/hash.go b/types/hash.go index 1613e89..d609a62 100644 --- a/types/hash.go +++ b/types/hash.go @@ -19,6 +19,8 @@ package types import ( "encoding/hex" "math/big" + + "google.golang.org/protobuf/types/known/wrapperspb" ) // Hash represents the 32 byte Keccak256 hash of arbitrary data. @@ -84,3 +86,11 @@ func (h *Hash) UnmarshalText(text []byte) error { *h = BytesToHash(FromHex(string(text))) return nil } + +// HashToWrapperspbBytes encodes hash as wrapperspb.BytesValue, nil if hash is nil +func HashToWrapperspbBytes(h *Hash) *wrapperspb.BytesValue { + if h == nil { + return nil + } + return wrapperspb.Bytes(h.Bytes()) +} diff --git a/types/uint256.go b/types/uint256.go deleted file mode 100644 index 638a413..0000000 --- a/types/uint256.go +++ /dev/null @@ -1,31 +0,0 @@ -package types - -import ( - "math/big" - - "github.com/holiman/uint256" -) - -// BytesToUint256 strictly returns nil if b is nil -func BytesToUint256(b []byte) *uint256.Int { - if b == nil { - return nil - } - return new(uint256.Int).SetBytes(b) -} - -// BytesToBigInt strictly returns nil if b is nil -func BytesToBigInt(b []byte) *big.Int { - if b == nil { - return nil - } - return new(big.Int).SetBytes(b) -} - -// BigIntToUint256 strictly returns nil if big is nil -func BigIntToUint256(i *big.Int) *uint256.Int { - if i == nil { - return nil - } - return uint256.MustFromBig(i) -} diff --git a/types/utils.go b/types/utils.go new file mode 100644 index 0000000..37f767e --- /dev/null +++ b/types/utils.go @@ -0,0 +1,40 @@ +package types + +import ( + "math/big" + + "github.com/holiman/uint256" + "google.golang.org/protobuf/types/known/wrapperspb" +) + +// BytesToUint256 strictly returns nil if byte array is nil +func BytesToUint256(b []byte) *uint256.Int { + if b == nil { + return nil + } + return new(uint256.Int).SetBytes(b) +} + +// BytesToBigInt strictly returns nil if byte array is nil +func BytesToBigInt(b []byte) *big.Int { + if b == nil { + return nil + } + return new(big.Int).SetBytes(b) +} + +// BigIntToUint256 strictly returns nil if big int is nil +func BigIntToUint256(i *big.Int) *uint256.Int { + if i == nil { + return nil + } + return uint256.MustFromBig(i) +} + +// BigIntToWrapperspbBytes strictly returns nil if big int is nil +func BigIntToWrapperspbBytes(i *big.Int) *wrapperspb.BytesValue { + if i == nil { + return nil + } + return wrapperspb.Bytes(i.Bytes()) +} From 942e4586fa40cefe3540026dbdd9de2537e7966d Mon Sep 17 00:00:00 2001 From: Rapol Date: Fri, 27 Sep 2024 13:31:45 +0200 Subject: [PATCH 18/27] gofmt --- db/substate_encoding.go | 15 +++----- db/substate_encoding_test.go | 22 ++++++------ protobuf/decode.go | 4 +-- protobuf/encode.go | 70 ++++++++++++++++++------------------ substate/message.go | 2 +- 5 files changed, 53 insertions(+), 60 deletions(-) diff --git a/db/substate_encoding.go b/db/substate_encoding.go index 0770c38..fe3a1a0 100644 --- a/db/substate_encoding.go +++ b/db/substate_encoding.go @@ -44,16 +44,11 @@ type substateEncoding struct { // decodeFunc aliases the common function used to decode substate type decodeFunc func([]byte, uint64, int) (*substate.Substate, error) -<<<<<<< HEAD // encodeFunc alias the common function used to encode substate type encodeFunc func(*substate.Substate, uint64, int) ([]byte, error) -// codeLookup aliases codehash->code lookup necessary to decode substate -type codeLookup = func(types.Hash) ([]byte, error) -======= // codeLookupFunc aliases codehash->code lookup necessary to decode substate type codeLookupFunc = func(types.Hash) ([]byte, error) ->>>>>>> main // newSubstateDecoder returns requested SubstateDecoder func newSubstateEncoding(encoding string, lookup codeLookupFunc) (*substateEncoding, error) { @@ -99,7 +94,6 @@ func (db *substateDB) encodeSubstate(ss *substate.Substate, block uint64, tx int return db.encoding.encode(ss, block, tx) } - // decodeRlp decodes into substate the provided rlp-encoded bytecode func decodeRlp(bytes []byte, lookup codeLookupFunc, block uint64, tx int) (*substate.Substate, error) { rlpSubstate, err := rlp.Decode(bytes) @@ -110,18 +104,18 @@ func decodeRlp(bytes []byte, lookup codeLookupFunc, block uint64, tx int) (*subs return rlpSubstate.ToSubstate(lookup, block, tx) } -//encodeRlp encodes into rlp-encoded bytes the provided substate +// encodeRlp encodes into rlp-encoded bytes the provided substate func encodeRlp(ss *substate.Substate, block uint64, tx int) ([]byte, error) { bytes, err := trlp.EncodeToBytes(rlp.NewRLP(ss)) if err != nil { return nil, fmt.Errorf("cannot encode substate into rlp block: %v, tx %v; %w", block, tx, err) } - + return bytes, nil } // decodeProtobuf decodes into substate the provided rlp-encoded bytecode -func decodeProtobuf(bytes []byte, lookup codeLookup, block uint64, tx int) (*substate.Substate, error) { +func decodeProtobuf(bytes []byte, lookup codeLookupFunc, block uint64, tx int) (*substate.Substate, error) { pbSubstate := &pb.Substate{} if err := proto.Unmarshal(bytes, pbSubstate); err != nil { return nil, fmt.Errorf("cannot decode substate data from protobuf block: %v, tx %v; %w", block, tx, err) @@ -130,7 +124,7 @@ func decodeProtobuf(bytes []byte, lookup codeLookup, block uint64, tx int) (*sub return pbSubstate.Decode(lookup, block, tx) } -//encodeRlp encodes into rlp-encoded bytes the provided substate +// encodeRlp encodes into rlp-encoded bytes the provided substate func encodeProtobuf(ss *substate.Substate, block uint64, tx int) ([]byte, error) { bytes, err := proto.Marshal(pb.Encode(ss)) if err != nil { @@ -139,4 +133,3 @@ func encodeProtobuf(ss *substate.Substate, block uint64, tx int) ([]byte, error) return bytes, nil } - diff --git a/db/substate_encoding_test.go b/db/substate_encoding_test.go index 39620ca..0636426 100644 --- a/db/substate_encoding_test.go +++ b/db/substate_encoding_test.go @@ -4,35 +4,35 @@ import ( "strings" "testing" - "google.golang.org/protobuf/proto" pb "github.com/Fantom-foundation/Substate/protobuf" "github.com/Fantom-foundation/Substate/rlp" trlp "github.com/Fantom-foundation/Substate/types/rlp" + "google.golang.org/protobuf/proto" ) type encTest struct { bytes []byte - blk uint64 - tx int + blk uint64 + tx int } var ( simplePb, _ = proto.Marshal(pb.Encode(testSubstate)) - testPb = encTest { + testPb = encTest{ bytes: simplePb, - blk: testSubstate.Block, - tx: testSubstate.Transaction, + blk: testSubstate.Block, + tx: testSubstate.Transaction, } simpleRlp, _ = trlp.EncodeToBytes(rlp.NewRLP(testSubstate)) - testRlp = encTest{ + testRlp = encTest{ bytes: simpleRlp, - blk: testSubstate.Block, - tx: testSubstate.Transaction, + blk: testSubstate.Block, + tx: testSubstate.Transaction, } supportedEncoding = map[string]encTest{ - "rlp": testRlp, + "rlp": testRlp, "protobuf": testPb, } ) @@ -119,7 +119,7 @@ func TestSubstateEncoding_TestDb(t *testing.T) { if err != nil { t.Error(err) } - + testSubstateDB_GetSubstate(db, t) } } diff --git a/protobuf/decode.go b/protobuf/decode.go index e56ee3d..5a613b5 100644 --- a/protobuf/decode.go +++ b/protobuf/decode.go @@ -5,10 +5,10 @@ import ( "fmt" "math/big" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/crypto" "github.com/Fantom-foundation/Substate/substate" "github.com/Fantom-foundation/Substate/types" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/crypto" "github.com/syndtr/goleveldb/leveldb" ) diff --git a/protobuf/encode.go b/protobuf/encode.go index 874b152..5e69e92 100644 --- a/protobuf/encode.go +++ b/protobuf/encode.go @@ -9,11 +9,11 @@ import ( // Encode converts aida-substate into protobuf-encoded message func Encode(ss *substate.Substate) *Substate { return &Substate{ - InputAlloc: encodeWorldState(ss.InputSubstate), + InputAlloc: encodeWorldState(ss.InputSubstate), OutputAlloc: encodeWorldState(ss.OutputSubstate), - BlockEnv: encodeEnv(ss.Env), - TxMessage: encodeMessage(ss.Message), - Result: encodeResult(ss.Result), + BlockEnv: encodeEnv(ss.Env), + TxMessage: encodeMessage(ss.Message), + Result: encodeResult(ss.Result), } } @@ -24,15 +24,15 @@ func encodeWorldState(sw substate.WorldState) *Substate_Alloc { storage := make([]*Substate_Account_StorageEntry, 0, len(acct.Storage)) for key, value := range acct.Storage { storage = append(storage, &Substate_Account_StorageEntry{ - Key: key.Bytes(), + Key: key.Bytes(), Value: value.Bytes(), }) } - world = append(world, &Substate_AllocEntry { + world = append(world, &Substate_AllocEntry{ Address: addr.Bytes(), Account: &Substate_Account{ - Nonce: &acct.Nonce, + Nonce: &acct.Nonce, Balance: acct.Balance.Bytes(), Storage: storage, Contract: &Substate_Account_CodeHash{ @@ -50,21 +50,21 @@ func encodeEnv(se *substate.Env) *Substate_BlockEnv { blockHashes := make([]*Substate_BlockEnv_BlockHashEntry, 0, len(se.BlockHashes)) for number, hash := range se.BlockHashes { blockHashes = append(blockHashes, &Substate_BlockEnv_BlockHashEntry{ - Key: &number, + Key: &number, Value: hash.Bytes(), }) } return &Substate_BlockEnv{ - Coinbase: se.Coinbase.Bytes(), - Difficulty: se.Difficulty.Bytes(), - GasLimit: &se.GasLimit, - Number: &se.Number, - Timestamp: &se.Timestamp, + Coinbase: se.Coinbase.Bytes(), + Difficulty: se.Difficulty.Bytes(), + GasLimit: &se.GasLimit, + Number: &se.Number, + Timestamp: &se.Timestamp, BlockHashes: blockHashes, - BaseFee: types.BigIntToWrapperspbBytes(se.BaseFee), + BaseFee: types.BigIntToWrapperspbBytes(se.BaseFee), BlobBaseFee: types.BigIntToWrapperspbBytes(se.BlobBaseFee), - Random: types.HashToWrapperspbBytes(se.Random), + Random: types.HashToWrapperspbBytes(se.Random), } } @@ -88,19 +88,19 @@ func encodeMessage(sm *substate.Message) *Substate_TxMessage { } return &Substate_TxMessage{ - Nonce: &sm.Nonce, - GasPrice: sm.GasPrice.Bytes(), - Gas: &sm.Gas, - From: sm.From.Bytes(), - To: types.AddressToWrapperspbBytes(sm.To), - Value: sm.Value.Bytes(), - Input: &Substate_TxMessage_Data{Data: sm.Data}, - TxType: txType, - AccessList: accessList, - GasFeeCap: types.BigIntToWrapperspbBytes(sm.GasFeeCap), - GasTipCap: types.BigIntToWrapperspbBytes(sm.GasTipCap), + Nonce: &sm.Nonce, + GasPrice: sm.GasPrice.Bytes(), + Gas: &sm.Gas, + From: sm.From.Bytes(), + To: types.AddressToWrapperspbBytes(sm.To), + Value: sm.Value.Bytes(), + Input: &Substate_TxMessage_Data{Data: sm.Data}, + TxType: txType, + AccessList: accessList, + GasFeeCap: types.BigIntToWrapperspbBytes(sm.GasFeeCap), + GasTipCap: types.BigIntToWrapperspbBytes(sm.GasTipCap), BlobGasFeeCap: types.BigIntToWrapperspbBytes(sm.BlobGasFeeCap), - BlobHashes: blobHashes, + BlobHashes: blobHashes, } } @@ -112,7 +112,7 @@ func (entry *Substate_TxMessage_AccessListEntry) encode(sat *types.AccessTuple) } entry = &Substate_TxMessage_AccessListEntry{ - Address: sat.Address.Bytes(), + Address: sat.Address.Bytes(), StorageKeys: keys, } } @@ -124,10 +124,10 @@ func encodeResult(sr *substate.Result) *Substate_Result { logs[i].encode(log) } - return &Substate_Result { - Status: &sr.Status, - Bloom: sr.Bloom.Bytes(), - Logs: logs, + return &Substate_Result{ + Status: &sr.Status, + Bloom: sr.Bloom.Bytes(), + Logs: logs, GasUsed: &sr.GasUsed, } } @@ -139,9 +139,9 @@ func (log *Substate_Result_Log) encode(sl *types.Log) { topics[i] = topic.Bytes() } - log = &Substate_Result_Log { + log = &Substate_Result_Log{ Address: sl.Address.Bytes(), - Topics: topics, - Data: sl.Data, + Topics: topics, + Data: sl.Data, } } diff --git a/substate/message.go b/substate/message.go index 4fee0a4..ab151e5 100644 --- a/substate/message.go +++ b/substate/message.go @@ -23,7 +23,7 @@ type Message struct { Data []byte // for memoization - dataHash *types.Hash + dataHash *types.Hash ProtobufTxType *int32 // when encoding pbuf // Berlin hard fork, EIP-2930: Optional access lists From 95d239877b8ec592050b0b25d957d9714cc6761f Mon Sep 17 00:00:00 2001 From: Rapol Date: Fri, 27 Sep 2024 13:44:05 +0200 Subject: [PATCH 19/27] refactor types/utils.go away --- protobuf/decode.go | 12 ++++++------ protobuf/encode.go | 14 +++++++------- protobuf/utils.go | 28 ++++++++++++++++++++++++++++ types/address.go | 10 ---------- types/hash.go | 10 ---------- types/utils.go | 40 ---------------------------------------- 6 files changed, 41 insertions(+), 73 deletions(-) delete mode 100644 types/utils.go diff --git a/protobuf/decode.go b/protobuf/decode.go index 5a613b5..daf5016 100644 --- a/protobuf/decode.go +++ b/protobuf/decode.go @@ -77,7 +77,7 @@ func (entry *Substate_AllocEntry) decode() ([]byte, *Substate_Account) { func (acct *Substate_Account) decode() (uint64, *big.Int, []byte, types.Hash) { return acct.GetNonce(), - types.BytesToBigInt(acct.GetBalance()), + BytesToBigInt(acct.GetBalance()), acct.GetCode(), types.BytesToHash(acct.GetCodeHash()) } @@ -99,7 +99,7 @@ func (env *Substate_BlockEnv) decode() *substate.Env { return &substate.Env{ Coinbase: types.BytesToAddress(env.GetCoinbase()), - Difficulty: types.BytesToBigInt(env.GetDifficulty()), + Difficulty: BytesToBigInt(env.GetDifficulty()), GasLimit: env.GetGasLimit(), Number: env.GetNumber(), Timestamp: env.GetTimestamp(), @@ -163,8 +163,8 @@ func (msg *Substate_TxMessage) decode(lookup dbGetCode) (*substate.Message, erro } // London hard fork, EIP-1559: Fee market - var gasFeeCap *big.Int = types.BytesToBigInt(msg.GetGasPrice()) - var gasTipCap *big.Int = types.BytesToBigInt(msg.GetGasPrice()) + var gasFeeCap *big.Int = BytesToBigInt(msg.GetGasPrice()) + var gasTipCap *big.Int = BytesToBigInt(msg.GetGasPrice()) switch txType { case Substate_TxMessage_TXTYPE_DYNAMICFEE, Substate_TxMessage_TXTYPE_BLOB: @@ -191,11 +191,11 @@ func (msg *Substate_TxMessage) decode(lookup dbGetCode) (*substate.Message, erro return &substate.Message{ Nonce: msg.GetNonce(), CheckNonce: true, - GasPrice: types.BytesToBigInt(msg.GetGasPrice()), + GasPrice: BytesToBigInt(msg.GetGasPrice()), Gas: msg.GetGas(), From: types.BytesToAddress(msg.GetFrom()), To: pTo, - Value: types.BytesToBigInt(msg.GetValue()), + Value: BytesToBigInt(msg.GetValue()), Data: data, AccessList: accessList, GasFeeCap: gasFeeCap, diff --git a/protobuf/encode.go b/protobuf/encode.go index 5e69e92..3284fa4 100644 --- a/protobuf/encode.go +++ b/protobuf/encode.go @@ -62,9 +62,9 @@ func encodeEnv(se *substate.Env) *Substate_BlockEnv { Number: &se.Number, Timestamp: &se.Timestamp, BlockHashes: blockHashes, - BaseFee: types.BigIntToWrapperspbBytes(se.BaseFee), - BlobBaseFee: types.BigIntToWrapperspbBytes(se.BlobBaseFee), - Random: types.HashToWrapperspbBytes(se.Random), + BaseFee: BigIntToWrapperspbBytes(se.BaseFee), + BlobBaseFee: BigIntToWrapperspbBytes(se.BlobBaseFee), + Random: HashToWrapperspbBytes(se.Random), } } @@ -92,14 +92,14 @@ func encodeMessage(sm *substate.Message) *Substate_TxMessage { GasPrice: sm.GasPrice.Bytes(), Gas: &sm.Gas, From: sm.From.Bytes(), - To: types.AddressToWrapperspbBytes(sm.To), + To: AddressToWrapperspbBytes(sm.To), Value: sm.Value.Bytes(), Input: &Substate_TxMessage_Data{Data: sm.Data}, TxType: txType, AccessList: accessList, - GasFeeCap: types.BigIntToWrapperspbBytes(sm.GasFeeCap), - GasTipCap: types.BigIntToWrapperspbBytes(sm.GasTipCap), - BlobGasFeeCap: types.BigIntToWrapperspbBytes(sm.BlobGasFeeCap), + GasFeeCap: BigIntToWrapperspbBytes(sm.GasFeeCap), + GasTipCap: BigIntToWrapperspbBytes(sm.GasTipCap), + BlobGasFeeCap: BigIntToWrapperspbBytes(sm.BlobGasFeeCap), BlobHashes: blobHashes, } } diff --git a/protobuf/utils.go b/protobuf/utils.go index f24a15b..f38ed48 100644 --- a/protobuf/utils.go +++ b/protobuf/utils.go @@ -29,3 +29,31 @@ func BytesValueToAddress(bv *wrapperspb.BytesValue) *types.Address { addr := types.BytesToAddress(bv.GetValue()) return &addr } + +func AddressToWrapperspbBytes(a *types.Address) *wrapperspb.BytesValue { + if a == nil { + return nil + } + return wrapperspb.Bytes(a.Bytes()) +} + +func HashToWrapperspbBytes(h *types.Hash) *wrapperspb.BytesValue { + if h == nil { + return nil + } + return wrapperspb.Bytes(h.Bytes()) +} + +func BigIntToWrapperspbBytes(i *big.Int) *wrapperspb.BytesValue { + if i == nil { + return nil + } + return wrapperspb.Bytes(i.Bytes()) +} + +func BytesToBigInt(b []byte) *big.Int { + if b == nil { + return nil + } + return new(big.Int).SetBytes(b) +} diff --git a/types/address.go b/types/address.go index 38fb144..ed2b7f8 100644 --- a/types/address.go +++ b/types/address.go @@ -2,8 +2,6 @@ package types import ( "encoding/hex" - - "google.golang.org/protobuf/types/known/wrapperspb" ) const AddressLength = 20 @@ -75,11 +73,3 @@ func (a *Address) UnmarshalText(text []byte) error { *a = BytesToAddress(FromHex(string(text))) return nil } - -// AddressToWrapperspbBytes returns address as wrapperspb.BytesValue, nil if address is nil -func AddressToWrapperspbBytes(a *Address) *wrapperspb.BytesValue { - if a == nil { - return nil - } - return wrapperspb.Bytes(a.Bytes()) -} diff --git a/types/hash.go b/types/hash.go index d609a62..1613e89 100644 --- a/types/hash.go +++ b/types/hash.go @@ -19,8 +19,6 @@ package types import ( "encoding/hex" "math/big" - - "google.golang.org/protobuf/types/known/wrapperspb" ) // Hash represents the 32 byte Keccak256 hash of arbitrary data. @@ -86,11 +84,3 @@ func (h *Hash) UnmarshalText(text []byte) error { *h = BytesToHash(FromHex(string(text))) return nil } - -// HashToWrapperspbBytes encodes hash as wrapperspb.BytesValue, nil if hash is nil -func HashToWrapperspbBytes(h *Hash) *wrapperspb.BytesValue { - if h == nil { - return nil - } - return wrapperspb.Bytes(h.Bytes()) -} diff --git a/types/utils.go b/types/utils.go deleted file mode 100644 index 37f767e..0000000 --- a/types/utils.go +++ /dev/null @@ -1,40 +0,0 @@ -package types - -import ( - "math/big" - - "github.com/holiman/uint256" - "google.golang.org/protobuf/types/known/wrapperspb" -) - -// BytesToUint256 strictly returns nil if byte array is nil -func BytesToUint256(b []byte) *uint256.Int { - if b == nil { - return nil - } - return new(uint256.Int).SetBytes(b) -} - -// BytesToBigInt strictly returns nil if byte array is nil -func BytesToBigInt(b []byte) *big.Int { - if b == nil { - return nil - } - return new(big.Int).SetBytes(b) -} - -// BigIntToUint256 strictly returns nil if big int is nil -func BigIntToUint256(i *big.Int) *uint256.Int { - if i == nil { - return nil - } - return uint256.MustFromBig(i) -} - -// BigIntToWrapperspbBytes strictly returns nil if big int is nil -func BigIntToWrapperspbBytes(i *big.Int) *wrapperspb.BytesValue { - if i == nil { - return nil - } - return wrapperspb.Bytes(i.Bytes()) -} From 9485797574f25334638d9c0b7057f967ce52ff29 Mon Sep 17 00:00:00 2001 From: Rapol Date: Fri, 27 Sep 2024 13:49:20 +0200 Subject: [PATCH 20/27] protobuf/decode.go --- protobuf/decode.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/protobuf/decode.go b/protobuf/decode.go index daf5016..cbf5970 100644 --- a/protobuf/decode.go +++ b/protobuf/decode.go @@ -139,7 +139,7 @@ func (msg *Substate_TxMessage) decode(lookup dbGetCode) (*substate.Message, erro txType := msg.GetTxType() // Berlin hard fork, EIP-2930: Optional access lists - var accessList types.AccessList = nil // nil if EIP-2930 is not activated + var accessList types.AccessList = []types.AccessTuple{} switch txType { case Substate_TxMessage_TXTYPE_ACCESSLIST, Substate_TxMessage_TXTYPE_DYNAMICFEE, From c798d7541b6041d88308d909bda1925b9b8eedd2 Mon Sep 17 00:00:00 2001 From: RT Date: Mon, 30 Sep 2024 07:35:36 +0000 Subject: [PATCH 21/27] revert go.mod chnages, geth1.14.8 go1.21 --- go.mod | 8 +++----- go.sum | 4 ++-- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/go.mod b/go.mod index 9f318f2..8cdf6eb 100644 --- a/go.mod +++ b/go.mod @@ -1,13 +1,10 @@ module github.com/Fantom-foundation/Substate -go 1.22 - -toolchain go1.22.4 +go 1.21 require ( - github.com/ethereum/go-ethereum v1.14.9 + github.com/ethereum/go-ethereum v1.14.8 github.com/golang/protobuf v1.5.4 - github.com/holiman/uint256 v1.3.1 github.com/stretchr/testify v1.9.0 github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 github.com/urfave/cli/v2 v2.25.7 @@ -21,6 +18,7 @@ require ( github.com/davecgh/go-spew v1.1.1 // indirect github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 // indirect github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb // indirect + github.com/holiman/uint256 v1.3.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect diff --git a/go.sum b/go.sum index 22155db..9d31cb4 100644 --- a/go.sum +++ b/go.sum @@ -10,8 +10,8 @@ github.com/decred/dcrd/crypto/blake256 v1.0.0 h1:/8DMNYp9SGi5f0w7uCm6d6M4OU2rGFK github.com/decred/dcrd/crypto/blake256 v1.0.0/go.mod h1:sQl2p6Y26YV+ZOcSTP6thNdn47hh8kt6rqSlvmrXFAc= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 h1:YLtO71vCjJRCBcrPMtQ9nqBsqpA1m5sE92cU+pd5Mcc= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1/go.mod h1:hyedUtir6IdtD/7lIxGeCxkaw7y45JueMRL4DIyJDKs= -github.com/ethereum/go-ethereum v1.14.9 h1:J7iwXDrtUyE9FUjUYbd4c9tyzwMh6dTJsKzo9i6SrwA= -github.com/ethereum/go-ethereum v1.14.9/go.mod h1:QeW+MtTpRdBEm2pUFoonByee8zfHv7kGp0wK0odvU1I= +github.com/ethereum/go-ethereum v1.14.8 h1:NgOWvXS+lauK+zFukEvi85UmmsS/OkV0N23UZ1VTIig= +github.com/ethereum/go-ethereum v1.14.8/go.mod h1:TJhyuDq0JDppAkFXgqjwpdlQApywnu/m10kFPxh8vvs= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= From 79974a431fa86c7484b5996c1cf472b923e4bd2a Mon Sep 17 00:00:00 2001 From: RT Date: Mon, 30 Sep 2024 08:00:22 +0000 Subject: [PATCH 22/27] defensive encoding check removed --- db/substate_db.go | 17 +++++++++++++---- db/substate_encoding.go | 12 +++--------- db/substate_encoding_test.go | 14 ++++++-------- 3 files changed, 22 insertions(+), 21 deletions(-) diff --git a/db/substate_db.go b/db/substate_db.go index 38601f1..a1ac9c5 100644 --- a/db/substate_db.go +++ b/db/substate_db.go @@ -61,11 +61,15 @@ func NewSubstateDB(path string, o *opt.Options, wo *opt.WriteOptions, ro *opt.Re } func MakeDefaultSubstateDB(db *leveldb.DB) SubstateDB { - return &substateDB{&codeDB{&baseDB{backend: db}}, nil} + sdb := &substateDB{&codeDB{&baseDB{backend: db}}, nil} + sdb, _ = sdb.SetSubstateEncoding("default") + return sdb } func MakeDefaultSubstateDBFromBaseDB(db BaseDB) SubstateDB { - return &substateDB{&codeDB{&baseDB{backend: db.getBackend()}}, nil} + sdb := &substateDB{&codeDB{&baseDB{backend: db.getBackend()}}, nil} + sdb, _ = sdb.SetSubstateEncoding("default") + return sdb } // NewReadOnlySubstateDB creates a new instance of read-only SubstateDB. @@ -74,7 +78,9 @@ func NewReadOnlySubstateDB(path string) (SubstateDB, error) { } func MakeSubstateDB(db *leveldb.DB, wo *opt.WriteOptions, ro *opt.ReadOptions) SubstateDB { - return &substateDB{&codeDB{&baseDB{backend: db, wo: wo, ro: ro}}, nil} + sdb := &substateDB{&codeDB{&baseDB{backend: db, wo: wo, ro: ro}}, nil} + sdb, _ = sdb.SetSubstateEncoding("default") + return sdb } func newSubstateDB(path string, o *opt.Options, wo *opt.WriteOptions, ro *opt.ReadOptions) (*substateDB, error) { @@ -82,7 +88,10 @@ func newSubstateDB(path string, o *opt.Options, wo *opt.WriteOptions, ro *opt.Re if err != nil { return nil, err } - return &substateDB{base, nil}, nil + + sdb := &substateDB{base, nil} + sdb, _ = sdb.SetSubstateEncoding("default") + return sdb, nil } type substateDB struct { diff --git a/db/substate_encoding.go b/db/substate_encoding.go index fe3a1a0..1a8c7e9 100644 --- a/db/substate_encoding.go +++ b/db/substate_encoding.go @@ -14,13 +14,13 @@ import ( // SetSubstateEncoding sets the runtime encoding/decoding behavior of substateDB // intended usage: // -// db := &substateDB{..} +// db := &substateDB{..} // default to rlp // db, err := db.SetSubstateEncoding() // set encoding // db.GetSubstateDecoder() // returns configured encoding func (db *substateDB) SetSubstateEncoding(schema string) (*substateDB, error) { encoding, err := newSubstateEncoding(schema, db.GetCode) if err != nil { - return nil, fmt.Errorf("Failed to set decoder; %w", err) + return nil, fmt.Errorf("failed to set decoder; %w", err) } db.encoding = encoding @@ -73,24 +73,18 @@ func newSubstateEncoding(encoding string, lookup codeLookupFunc) (*substateEncod }, nil default: - return nil, fmt.Errorf("Encoding not supported: %s", encoding) + return nil, fmt.Errorf("encoding not supported: %s", encoding) } } // decodeSubstate defensively defaults to "default" if nil func (db *substateDB) decodeToSubstate(bytes []byte, block uint64, tx int) (*substate.Substate, error) { - if db.encoding == nil { - db.SetSubstateEncoding("default") - } return db.encoding.decode(bytes, block, tx) } // encodeSubstate defensively defaults to "default" if nil func (db *substateDB) encodeSubstate(ss *substate.Substate, block uint64, tx int) ([]byte, error) { - if db.encoding == nil { - db.SetSubstateEncoding("default") - } return db.encoding.encode(ss, block, tx) } diff --git a/db/substate_encoding_test.go b/db/substate_encoding_test.go index 0636426..1583ae4 100644 --- a/db/substate_encoding_test.go +++ b/db/substate_encoding_test.go @@ -44,19 +44,17 @@ func TestSubstateEncoding_NilEncodingDefaultsToRlp(t *testing.T) { t.Errorf("cannot open db; %v", err) } - if got := db.GetSubstateEncoding(); got != "" { + // purposely never set encoding + + // defaults to rlp + if got := db.GetSubstateEncoding(); got != "rlp" { t.Fatalf("substate encoding should be nil, got: %s", got) } - // purposely never set encoding _, err = db.decodeToSubstate(testRlp.bytes, testRlp.blk, testRlp.tx) if err != nil { t.Fatal(err) } - - if got := db.GetSubstateEncoding(); got != "rlp" { - t.Fatalf("db should default to rlp, got: %s", got) - } } func TestSubstateEncoding_DefaultEncodingDefaultsToRlp(t *testing.T) { @@ -92,8 +90,8 @@ func TestSubstateEncoding_UnsupportedEncodingThrowsError(t *testing.T) { } _, err = db.SetSubstateEncoding("EncodingNotSupported") - if err == nil || !strings.Contains(err.Error(), "Encoding not supported") { - t.Error("Encoding not supported, but no error") + if err == nil || !strings.Contains(err.Error(), "encoding not supported") { + t.Error("encoding not supported, but no error") } } From eeda2a4333b81774d29a41741c8e4bdb6d20741f Mon Sep 17 00:00:00 2001 From: RT Date: Mon, 30 Sep 2024 09:00:32 +0000 Subject: [PATCH 23/27] remove geth dependency --- go.mod | 1 - protobuf/decode.go | 45 ++++++++++++++++++++++++--------------------- types/hash/hash.go | 11 +++++++++++ 3 files changed, 35 insertions(+), 22 deletions(-) diff --git a/go.mod b/go.mod index 8cdf6eb..5ed64e3 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,6 @@ module github.com/Fantom-foundation/Substate go 1.21 require ( - github.com/ethereum/go-ethereum v1.14.8 github.com/golang/protobuf v1.5.4 github.com/stretchr/testify v1.9.0 github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 diff --git a/protobuf/decode.go b/protobuf/decode.go index cbf5970..0c2ed77 100644 --- a/protobuf/decode.go +++ b/protobuf/decode.go @@ -7,8 +7,8 @@ import ( "github.com/Fantom-foundation/Substate/substate" "github.com/Fantom-foundation/Substate/types" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/crypto" + "github.com/Fantom-foundation/Substate/types/hash" + trlp "github.com/Fantom-foundation/Substate/types/rlp" "github.com/syndtr/goleveldb/leveldb" ) @@ -209,35 +209,38 @@ func (entry *Substate_TxMessage_AccessListEntry) decode() ([]byte, [][]byte) { return entry.GetAddress(), entry.GetStorageKeys() } -// getContractAddress returns the address of the newly created contract if any. -// returns nil otherwise. -func (msg *Substate_TxMessage) getContractAddress() common.Address { - var contractAddress common.Address - - // *to==nil means contract creation and thus address of newly created contract - to := msg.GetTo() - if to == nil { - fromAddr := common.BytesToAddress(msg.GetFrom()) - contractAddress = crypto.CreateAddress(fromAddr, msg.GetNonce()) +// getContractAddress returns, the address.Bytes() of the newly created contract, +// returns nil if no contract is created. +func (msg *Substate_TxMessage) getContractAddress() types.Address { + // *to==nil means no contract creation + if msg.GetTo() != nil { + return types.Address{} } - return contractAddress + return createAddress(types.BytesToAddress(msg.GetFrom()), msg.GetNonce()) +} + +// createAddress creates an address given the bytes and the nonce +// mimics crypto.CreateAddress, to avoid cyclical dependency. +func createAddress(addr types.Address, nonce uint64) types.Address { + data, _ := trlp.EncodeToBytes([]interface{}{addr, nonce}) + return types.BytesToAddress(hash.Keccak256(data)[12:]) } // decode converts protobuf-encoded Substate_Result into aida-comprehensible Result -func (res *Substate_Result) decode(contractAddress common.Address) *substate.Result { +func (res *Substate_Result) decode(contractAddress types.Address) *substate.Result { logs := make([]*types.Log, len(res.GetLogs())) for i, log := range res.GetLogs() { logs[i] = log.decode() } - return substate.NewResult( - res.GetStatus(), // Status - types.BytesToBloom(res.Bloom), // Bloom - logs, // Logs - types.BytesToAddress(contractAddress.Bytes()), // ContractAddress - res.GetGasUsed(), // GasUsed - ) + return &substate.Result{ + Status: res.GetStatus(), + Bloom: types.BytesToBloom(res.Bloom), + Logs: logs, + ContractAddress: contractAddress, + GasUsed: res.GetGasUsed(), + } } func (log *Substate_Result_Log) decode() *types.Log { diff --git a/types/hash/hash.go b/types/hash/hash.go index 0dd2511..45d3647 100644 --- a/types/hash/hash.go +++ b/types/hash/hash.go @@ -37,6 +37,17 @@ func NewKeccakState() KeccakState { return sha3.NewLegacyKeccak256().(KeccakState) } +// Keccak256 calculates and returns the Keccak256 hash of the input data. +func Keccak256(data ...[]byte) []byte { + b := make([]byte, 32) + d := NewKeccakState() + for _, b := range data { + d.Write(b) + } + d.Read(b) + return b +} + // Keccak256Hash calculates and returns the Keccak256 hash of the input data, // converting it to an internal Hash data structure. func Keccak256Hash(data ...[]byte) (h types.Hash) { From 50d95eaf341f0bf64927caf602ff95d433051443 Mon Sep 17 00:00:00 2001 From: RT <146690782+rpl-ffl@users.noreply.github.com> Date: Mon, 30 Sep 2024 16:03:44 +0700 Subject: [PATCH 24/27] Apply suggestions from code review comments on encode***( Co-authored-by: cabrador <84449820+cabrador@users.noreply.github.com> --- db/substate_encoding.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/db/substate_encoding.go b/db/substate_encoding.go index 1a8c7e9..f5458f8 100644 --- a/db/substate_encoding.go +++ b/db/substate_encoding.go @@ -98,7 +98,7 @@ func decodeRlp(bytes []byte, lookup codeLookupFunc, block uint64, tx int) (*subs return rlpSubstate.ToSubstate(lookup, block, tx) } -// encodeRlp encodes into rlp-encoded bytes the provided substate +// encodeRlp encodes substate into rlp-encoded bytes func encodeRlp(ss *substate.Substate, block uint64, tx int) ([]byte, error) { bytes, err := trlp.EncodeToBytes(rlp.NewRLP(ss)) if err != nil { @@ -108,7 +108,7 @@ func encodeRlp(ss *substate.Substate, block uint64, tx int) ([]byte, error) { return bytes, nil } -// decodeProtobuf decodes into substate the provided rlp-encoded bytecode +// decodeProtobuf decodes protobuf-encoded bytecode into substate func decodeProtobuf(bytes []byte, lookup codeLookupFunc, block uint64, tx int) (*substate.Substate, error) { pbSubstate := &pb.Substate{} if err := proto.Unmarshal(bytes, pbSubstate); err != nil { @@ -118,7 +118,7 @@ func decodeProtobuf(bytes []byte, lookup codeLookupFunc, block uint64, tx int) ( return pbSubstate.Decode(lookup, block, tx) } -// encodeRlp encodes into rlp-encoded bytes the provided substate +// encodeProtobuf encodes substate into protobuf-encoded bytes func encodeProtobuf(ss *substate.Substate, block uint64, tx int) ([]byte, error) { bytes, err := proto.Marshal(pb.Encode(ss)) if err != nil { From a660d9b6b0a5a8bd3fd9548318927637bee943a4 Mon Sep 17 00:00:00 2001 From: RT Date: Mon, 30 Sep 2024 09:05:21 +0000 Subject: [PATCH 25/27] dbGetCode -> getCodeFunc --- protobuf/decode.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/protobuf/decode.go b/protobuf/decode.go index 0c2ed77..94c837a 100644 --- a/protobuf/decode.go +++ b/protobuf/decode.go @@ -12,10 +12,10 @@ import ( "github.com/syndtr/goleveldb/leveldb" ) -type dbGetCode = func(types.Hash) ([]byte, error) +type getCodeFunc = func(types.Hash) ([]byte, error) // Decode converts protobuf-encoded Substate into aida-comprehensible substate -func (s *Substate) Decode(lookup dbGetCode, block uint64, tx int) (*substate.Substate, error) { +func (s *Substate) Decode(lookup getCodeFunc, block uint64, tx int) (*substate.Substate, error) { input, err := s.GetInputAlloc().decode(lookup) if err != nil { return nil, err @@ -48,7 +48,7 @@ func (s *Substate) Decode(lookup dbGetCode, block uint64, tx int) (*substate.Sub } // decode converts protobuf-encoded Substate_Alloc into aida-comprehensible WorldState -func (alloc *Substate_Alloc) decode(lookup dbGetCode) (*substate.WorldState, error) { +func (alloc *Substate_Alloc) decode(lookup getCodeFunc) (*substate.WorldState, error) { world := make(substate.WorldState, len(alloc.GetAlloc())) for _, entry := range alloc.GetAlloc() { @@ -115,7 +115,7 @@ func (entry *Substate_BlockEnv_BlockHashEntry) decode() (uint64, []byte) { } // decode converts protobuf-encoded Substate_TxMessage into aida-comprehensible Message -func (msg *Substate_TxMessage) decode(lookup dbGetCode) (*substate.Message, error) { +func (msg *Substate_TxMessage) decode(lookup getCodeFunc) (*substate.Message, error) { // to=nil means contract creation var pTo *types.Address = nil From e68fe3cc0a8f991289ba67a319292a1bc48d3ab4 Mon Sep 17 00:00:00 2001 From: RT Date: Mon, 30 Sep 2024 09:23:26 +0000 Subject: [PATCH 26/27] encode -> toProtobuf --- db/substate_encoding.go | 14 ++------------ db/substate_encoding_test.go | 18 ++++++------------ protobuf/decode.go | 2 +- protobuf/encode.go | 34 +++++++++++++++++++++++----------- protobuf/utils.go | 2 +- 5 files changed, 33 insertions(+), 37 deletions(-) diff --git a/db/substate_encoding.go b/db/substate_encoding.go index f5458f8..af808e5 100644 --- a/db/substate_encoding.go +++ b/db/substate_encoding.go @@ -69,7 +69,7 @@ func newSubstateEncoding(encoding string, lookup codeLookupFunc) (*substateEncod decode: func(bytes []byte, block uint64, tx int) (*substate.Substate, error) { return decodeProtobuf(bytes, lookup, block, tx) }, - encode: encodeProtobuf, + encode: pb.Encode, }, nil default: @@ -98,7 +98,7 @@ func decodeRlp(bytes []byte, lookup codeLookupFunc, block uint64, tx int) (*subs return rlpSubstate.ToSubstate(lookup, block, tx) } -// encodeRlp encodes substate into rlp-encoded bytes +// encodeRlp encodes substate into rlp-encoded bytes func encodeRlp(ss *substate.Substate, block uint64, tx int) ([]byte, error) { bytes, err := trlp.EncodeToBytes(rlp.NewRLP(ss)) if err != nil { @@ -117,13 +117,3 @@ func decodeProtobuf(bytes []byte, lookup codeLookupFunc, block uint64, tx int) ( return pbSubstate.Decode(lookup, block, tx) } - -// encodeProtobuf encodes substate into protobuf-encoded bytes -func encodeProtobuf(ss *substate.Substate, block uint64, tx int) ([]byte, error) { - bytes, err := proto.Marshal(pb.Encode(ss)) - if err != nil { - return nil, fmt.Errorf("cannot encode substate into protobuf block: %v, tx %v; %w", block, tx, err) - } - - return bytes, nil -} diff --git a/db/substate_encoding_test.go b/db/substate_encoding_test.go index 1583ae4..23d57c5 100644 --- a/db/substate_encoding_test.go +++ b/db/substate_encoding_test.go @@ -7,7 +7,6 @@ import ( pb "github.com/Fantom-foundation/Substate/protobuf" "github.com/Fantom-foundation/Substate/rlp" trlp "github.com/Fantom-foundation/Substate/types/rlp" - "google.golang.org/protobuf/proto" ) type encTest struct { @@ -17,19 +16,14 @@ type encTest struct { } var ( - simplePb, _ = proto.Marshal(pb.Encode(testSubstate)) - testPb = encTest{ - bytes: simplePb, - blk: testSubstate.Block, - tx: testSubstate.Transaction, - } + blk = testSubstate.Block + tx = testSubstate.Transaction + + simplePb, _ = pb.Encode(testSubstate, blk, tx) + testPb = encTest{bytes: simplePb, blk: blk, tx: tx} simpleRlp, _ = trlp.EncodeToBytes(rlp.NewRLP(testSubstate)) - testRlp = encTest{ - bytes: simpleRlp, - blk: testSubstate.Block, - tx: testSubstate.Transaction, - } + testRlp = encTest{bytes: simpleRlp, blk: blk, tx: tx} supportedEncoding = map[string]encTest{ "rlp": testRlp, diff --git a/protobuf/decode.go b/protobuf/decode.go index 94c837a..edfff38 100644 --- a/protobuf/decode.go +++ b/protobuf/decode.go @@ -14,7 +14,7 @@ import ( type getCodeFunc = func(types.Hash) ([]byte, error) -// Decode converts protobuf-encoded Substate into aida-comprehensible substate +// Decode converts protobuf-encoded bytes into aida substate func (s *Substate) Decode(lookup getCodeFunc, block uint64, tx int) (*substate.Substate, error) { input, err := s.GetInputAlloc().decode(lookup) if err != nil { diff --git a/protobuf/encode.go b/protobuf/encode.go index 3284fa4..0c3527b 100644 --- a/protobuf/encode.go +++ b/protobuf/encode.go @@ -1,24 +1,36 @@ package protobuf import ( + "fmt" + "github.com/Fantom-foundation/Substate/substate" "github.com/Fantom-foundation/Substate/types" "github.com/Fantom-foundation/Substate/types/hash" + "google.golang.org/protobuf/proto" ) // Encode converts aida-substate into protobuf-encoded message -func Encode(ss *substate.Substate) *Substate { +func Encode(ss *substate.Substate, block uint64, tx int) ([]byte, error) { + bytes, err := proto.Marshal(toProtobufSubstate(ss)) + if err != nil { + return nil, fmt.Errorf("cannot encode substate into protobuf block: %v,tx %v; %w", block, tx, err) + } + + return bytes, nil +} + +func toProtobufSubstate(ss *substate.Substate) *Substate { return &Substate{ - InputAlloc: encodeWorldState(ss.InputSubstate), - OutputAlloc: encodeWorldState(ss.OutputSubstate), - BlockEnv: encodeEnv(ss.Env), - TxMessage: encodeMessage(ss.Message), - Result: encodeResult(ss.Result), + InputAlloc: toProtobufAlloc(ss.InputSubstate), + OutputAlloc: toProtobufAlloc(ss.OutputSubstate), + BlockEnv: toProtobufBlockEnv(ss.Env), + TxMessage: toProtobufTxMessage(ss.Message), + Result: toProtobufResult(ss.Result), } } -// encodeWorldState converts substate.WorldState into protobuf-encoded Substate_Alloc -func encodeWorldState(sw substate.WorldState) *Substate_Alloc { +// toProtobufAlloc converts substate.WorldState into protobuf-encoded Substate_Alloc +func toProtobufAlloc(sw substate.WorldState) *Substate_Alloc { world := make([]*Substate_AllocEntry, 0, len(sw)) for addr, acct := range sw { storage := make([]*Substate_Account_StorageEntry, 0, len(acct.Storage)) @@ -46,7 +58,7 @@ func encodeWorldState(sw substate.WorldState) *Substate_Alloc { } // encode converts substate.Env into protobuf-encoded Substate_BlockEnv -func encodeEnv(se *substate.Env) *Substate_BlockEnv { +func toProtobufBlockEnv(se *substate.Env) *Substate_BlockEnv { blockHashes := make([]*Substate_BlockEnv_BlockHashEntry, 0, len(se.BlockHashes)) for number, hash := range se.BlockHashes { blockHashes = append(blockHashes, &Substate_BlockEnv_BlockHashEntry{ @@ -69,7 +81,7 @@ func encodeEnv(se *substate.Env) *Substate_BlockEnv { } // encode converts substate.Message into protobuf-encoded Substate_TxMessage -func encodeMessage(sm *substate.Message) *Substate_TxMessage { +func toProtobufTxMessage(sm *substate.Message) *Substate_TxMessage { dt := Substate_TxMessage_TXTYPE_LEGACY txType := &dt if sm.ProtobufTxType != nil { @@ -118,7 +130,7 @@ func (entry *Substate_TxMessage_AccessListEntry) encode(sat *types.AccessTuple) } // encode converts substate.Results into protobuf-encoded Substate_Result -func encodeResult(sr *substate.Result) *Substate_Result { +func toProtobufResult(sr *substate.Result) *Substate_Result { logs := make([]*Substate_Result_Log, len(sr.Logs)) for i, log := range sr.Logs { logs[i].encode(log) diff --git a/protobuf/utils.go b/protobuf/utils.go index f38ed48..3fde686 100644 --- a/protobuf/utils.go +++ b/protobuf/utils.go @@ -55,5 +55,5 @@ func BytesToBigInt(b []byte) *big.Int { if b == nil { return nil } - return new(big.Int).SetBytes(b) + return new(big.Int).SetBytes(b) } From d12af8cad7efc277eafcc0260fd9af63b2a3d40f Mon Sep 17 00:00:00 2001 From: RT Date: Mon, 30 Sep 2024 09:28:59 +0000 Subject: [PATCH 27/27] encode -> toProtobufOOO for missing func --- protobuf/encode.go | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/protobuf/encode.go b/protobuf/encode.go index 0c3527b..55fda6c 100644 --- a/protobuf/encode.go +++ b/protobuf/encode.go @@ -91,7 +91,7 @@ func toProtobufTxMessage(sm *substate.Message) *Substate_TxMessage { accessList := make([]*Substate_TxMessage_AccessListEntry, len(sm.AccessList)) for i, entry := range sm.AccessList { - accessList[i].encode(&entry) + accessList[i].toProtobufAccessListEntry(&entry) } blobHashes := make([][]byte, len(sm.BlobHashes)) @@ -116,8 +116,8 @@ func toProtobufTxMessage(sm *substate.Message) *Substate_TxMessage { } } -// encode converts types.AccessTuple into protobuf-encoded Substate_TxMessage_AccessListEntry -func (entry *Substate_TxMessage_AccessListEntry) encode(sat *types.AccessTuple) { +// toProtobufAccessListEntry converts types.AccessTuple into protobuf-encoded Substate_TxMessage_AccessListEntry +func (entry *Substate_TxMessage_AccessListEntry) toProtobufAccessListEntry(sat *types.AccessTuple) { keys := make([][]byte, len(sat.StorageKeys)) for i, key := range sat.StorageKeys { keys[i] = key.Bytes() @@ -133,7 +133,7 @@ func (entry *Substate_TxMessage_AccessListEntry) encode(sat *types.AccessTuple) func toProtobufResult(sr *substate.Result) *Substate_Result { logs := make([]*Substate_Result_Log, len(sr.Logs)) for i, log := range sr.Logs { - logs[i].encode(log) + logs[i].toProtobufLog(log) } return &Substate_Result{ @@ -144,8 +144,8 @@ func toProtobufResult(sr *substate.Result) *Substate_Result { } } -// encode converts types.Log into protobuf-encoded Substate_Result_log -func (log *Substate_Result_Log) encode(sl *types.Log) { +// toProtobufLog converts types.Log into protobuf-encoded Substate_Result_log +func (log *Substate_Result_Log) toProtobufLog(sl *types.Log) { topics := make([][]byte, len(sl.Topics)) for i, topic := range sl.Topics { topics[i] = topic.Bytes()