NFT Token Detail
Token ID | 1 |
Contract | 0xcdA9FC258358EcaA88845f19Af595e908bb7EfE9 Contract 205 |
Contract type | ERC20 |
Metadata
Loading metadata from https://ipfs.io/ipfs/cda9fc258358ecaa88845f19af595e908bb7efe9.json...
From 0ab89bd6314ead04dd012be35787d5aee9632277 Mon Sep 17 00:00:00 2001 From: kaladinlight <35275952+kaladinlight@users.noreply.github.com> Date: Mon, 22 Apr 2024 11:22:59 -0600 Subject: [PATCH 01/13] add base support --- bchain/coins/base/baserpc.go | 83 ++++++ bchain/coins/blockchain.go | 2 + bchain/coins/eth/ethaddrcontracts.pb.go | 365 ++++++++++++++++++++++++ bchain/coins/eth/ethaddrcontracts.proto | 22 ++ bchain/coins/eth/ethtx.pb.go | 4 +- blockbook.go | 9 +- configs/coins/base.json | 64 +++++ db/bulkconnect.go | 42 ++- db/rocksdb.go | 68 +++-- db/rocksdb_ethereumtype.go | 115 +++++--- 10 files changed, 693 insertions(+), 81 deletions(-) create mode 100644 bchain/coins/base/baserpc.go create mode 100644 bchain/coins/eth/ethaddrcontracts.pb.go create mode 100644 bchain/coins/eth/ethaddrcontracts.proto create mode 100644 configs/coins/base.json diff --git a/bchain/coins/base/baserpc.go b/bchain/coins/base/baserpc.go new file mode 100644 index 0000000000..fecf9327a5 --- /dev/null +++ b/bchain/coins/base/baserpc.go @@ -0,0 +1,83 @@ +package base + +import ( + "context" + "encoding/json" + + "github.com/ethereum/go-ethereum/ethclient" + "github.com/ethereum/go-ethereum/rpc" + "github.com/golang/glog" + "github.com/juju/errors" + "github.com/trezor/blockbook/bchain" + "github.com/trezor/blockbook/bchain/coins/eth" +) + +const ( + // MainNet is production network + MainNet eth.Network = 8453 +) + +// BaseRPC is an interface to JSON-RPC base service. +type BaseRPC struct { + *eth.EthereumRPC +} + +// NewBaseRPC returns new BaseRPC instance. +func NewBaseRPC(config json.RawMessage, pushHandler func(bchain.NotificationType)) (bchain.BlockChain, error) { + c, err := eth.NewEthereumRPC(config, pushHandler) + if err != nil { + return nil, err + } + + s := &BaseRPC{ + EthereumRPC: c.(*eth.EthereumRPC), + } + + return s, nil +} + +// Initialize base rpc interface +func (b *BaseRPC) Initialize() error { + b.OpenRPC = func(url string) (bchain.EVMRPCClient, bchain.EVMClient, error) { + r, err := rpc.Dial(url) + if err != nil { + return nil, nil, err + } + rc := ð.EthereumRPCClient{Client: r} + ec := ð.EthereumClient{Client: ethclient.NewClient(r)} + return rc, ec, nil + } + + rc, ec, err := b.OpenRPC(b.ChainConfig.RPCURL) + if err != nil { + return err + } + + // set chain specific + b.Client = ec + b.RPC = rc + b.MainNetChainID = MainNet + b.NewBlock = eth.NewEthereumNewBlock() + b.NewTx = eth.NewEthereumNewTx() + + ctx, cancel := context.WithTimeout(context.Background(), b.Timeout) + defer cancel() + + id, err := b.Client.NetworkID(ctx) + if err != nil { + return err + } + + // parameters for getInfo request + switch eth.Network(id.Uint64()) { + case MainNet: + b.Testnet = false + b.Network = "livenet" + default: + return errors.Errorf("Unknown network id %v", id) + } + + glog.Info("rpc: block chain ", b.Network) + + return nil +} diff --git a/bchain/coins/blockchain.go b/bchain/coins/blockchain.go index e694dafca8..e843174f36 100644 --- a/bchain/coins/blockchain.go +++ b/bchain/coins/blockchain.go @@ -13,6 +13,7 @@ import ( "github.com/trezor/blockbook/bchain" "github.com/trezor/blockbook/bchain/coins/arbitrum" "github.com/trezor/blockbook/bchain/coins/avalanche" + "github.com/trezor/blockbook/bchain/coins/base" "github.com/trezor/blockbook/bchain/coins/bch" "github.com/trezor/blockbook/bchain/coins/bellcoin" "github.com/trezor/blockbook/bchain/coins/bitcore" @@ -147,6 +148,7 @@ func init() { BlockChainFactories["Arbitrum Archive"] = arbitrum.NewArbitrumRPC BlockChainFactories["Arbitrum Nova"] = arbitrum.NewArbitrumRPC BlockChainFactories["Arbitrum Nova Archive"] = arbitrum.NewArbitrumRPC + BlockChainFactories["Base"] = base.NewBaseRPC } // NewBlockChain creates bchain.BlockChain and bchain.Mempool for the coin passed by the parameter coin diff --git a/bchain/coins/eth/ethaddrcontracts.pb.go b/bchain/coins/eth/ethaddrcontracts.pb.go new file mode 100644 index 0000000000..a57f6687a6 --- /dev/null +++ b/bchain/coins/eth/ethaddrcontracts.pb.go @@ -0,0 +1,365 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.33.0 +// protoc v4.25.3 +// source: bchain/coins/eth/ethaddrcontracts.proto + +package eth + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + 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 ProtoAddrContracts struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + TotalTxs uint64 `protobuf:"varint,1,opt,name=TotalTxs,proto3" json:"TotalTxs,omitempty"` + NonContractTxs uint64 `protobuf:"varint,2,opt,name=NonContractTxs,proto3" json:"NonContractTxs,omitempty"` + InternalTxs uint64 `protobuf:"varint,3,opt,name=InternalTxs,proto3" json:"InternalTxs,omitempty"` + Contracts []*ProtoAddrContracts_AddrContract `protobuf:"bytes,4,rep,name=Contracts,proto3" json:"Contracts,omitempty"` +} + +func (x *ProtoAddrContracts) Reset() { + *x = ProtoAddrContracts{} + if protoimpl.UnsafeEnabled { + mi := &file_bchain_coins_eth_ethaddrcontracts_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ProtoAddrContracts) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ProtoAddrContracts) ProtoMessage() {} + +func (x *ProtoAddrContracts) ProtoReflect() protoreflect.Message { + mi := &file_bchain_coins_eth_ethaddrcontracts_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 ProtoAddrContracts.ProtoReflect.Descriptor instead. +func (*ProtoAddrContracts) Descriptor() ([]byte, []int) { + return file_bchain_coins_eth_ethaddrcontracts_proto_rawDescGZIP(), []int{0} +} + +func (x *ProtoAddrContracts) GetTotalTxs() uint64 { + if x != nil { + return x.TotalTxs + } + return 0 +} + +func (x *ProtoAddrContracts) GetNonContractTxs() uint64 { + if x != nil { + return x.NonContractTxs + } + return 0 +} + +func (x *ProtoAddrContracts) GetInternalTxs() uint64 { + if x != nil { + return x.InternalTxs + } + return 0 +} + +func (x *ProtoAddrContracts) GetContracts() []*ProtoAddrContracts_AddrContract { + if x != nil { + return x.Contracts + } + return nil +} + +type ProtoAddrContracts_MultiTokenValue struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id []byte `protobuf:"bytes,1,opt,name=Id,proto3" json:"Id,omitempty"` + Value []byte `protobuf:"bytes,2,opt,name=Value,proto3" json:"Value,omitempty"` +} + +func (x *ProtoAddrContracts_MultiTokenValue) Reset() { + *x = ProtoAddrContracts_MultiTokenValue{} + if protoimpl.UnsafeEnabled { + mi := &file_bchain_coins_eth_ethaddrcontracts_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ProtoAddrContracts_MultiTokenValue) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ProtoAddrContracts_MultiTokenValue) ProtoMessage() {} + +func (x *ProtoAddrContracts_MultiTokenValue) ProtoReflect() protoreflect.Message { + mi := &file_bchain_coins_eth_ethaddrcontracts_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 ProtoAddrContracts_MultiTokenValue.ProtoReflect.Descriptor instead. +func (*ProtoAddrContracts_MultiTokenValue) Descriptor() ([]byte, []int) { + return file_bchain_coins_eth_ethaddrcontracts_proto_rawDescGZIP(), []int{0, 0} +} + +func (x *ProtoAddrContracts_MultiTokenValue) GetId() []byte { + if x != nil { + return x.Id + } + return nil +} + +func (x *ProtoAddrContracts_MultiTokenValue) GetValue() []byte { + if x != nil { + return x.Value + } + return nil +} + +type ProtoAddrContracts_AddrContract struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Type int64 `protobuf:"varint,1,opt,name=Type,proto3" json:"Type,omitempty"` + Contract []byte `protobuf:"bytes,2,opt,name=Contract,proto3" json:"Contract,omitempty"` + Txs uint64 `protobuf:"varint,3,opt,name=Txs,proto3" json:"Txs,omitempty"` + Value []byte `protobuf:"bytes,4,opt,name=Value,proto3" json:"Value,omitempty"` + Ids [][]byte `protobuf:"bytes,5,rep,name=Ids,proto3" json:"Ids,omitempty"` + MultiTokenValues []*ProtoAddrContracts_MultiTokenValue `protobuf:"bytes,6,rep,name=MultiTokenValues,proto3" json:"MultiTokenValues,omitempty"` +} + +func (x *ProtoAddrContracts_AddrContract) Reset() { + *x = ProtoAddrContracts_AddrContract{} + if protoimpl.UnsafeEnabled { + mi := &file_bchain_coins_eth_ethaddrcontracts_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ProtoAddrContracts_AddrContract) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ProtoAddrContracts_AddrContract) ProtoMessage() {} + +func (x *ProtoAddrContracts_AddrContract) ProtoReflect() protoreflect.Message { + mi := &file_bchain_coins_eth_ethaddrcontracts_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 ProtoAddrContracts_AddrContract.ProtoReflect.Descriptor instead. +func (*ProtoAddrContracts_AddrContract) Descriptor() ([]byte, []int) { + return file_bchain_coins_eth_ethaddrcontracts_proto_rawDescGZIP(), []int{0, 1} +} + +func (x *ProtoAddrContracts_AddrContract) GetType() int64 { + if x != nil { + return x.Type + } + return 0 +} + +func (x *ProtoAddrContracts_AddrContract) GetContract() []byte { + if x != nil { + return x.Contract + } + return nil +} + +func (x *ProtoAddrContracts_AddrContract) GetTxs() uint64 { + if x != nil { + return x.Txs + } + return 0 +} + +func (x *ProtoAddrContracts_AddrContract) GetValue() []byte { + if x != nil { + return x.Value + } + return nil +} + +func (x *ProtoAddrContracts_AddrContract) GetIds() [][]byte { + if x != nil { + return x.Ids + } + return nil +} + +func (x *ProtoAddrContracts_AddrContract) GetMultiTokenValues() []*ProtoAddrContracts_MultiTokenValue { + if x != nil { + return x.MultiTokenValues + } + return nil +} + +var File_bchain_coins_eth_ethaddrcontracts_proto protoreflect.FileDescriptor + +var file_bchain_coins_eth_ethaddrcontracts_proto_rawDesc = []byte{ + 0x0a, 0x27, 0x62, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x2f, 0x63, 0x6f, 0x69, 0x6e, 0x73, 0x2f, 0x65, + 0x74, 0x68, 0x2f, 0x65, 0x74, 0x68, 0x61, 0x64, 0x64, 0x72, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, + 0x63, 0x74, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xbf, 0x03, 0x0a, 0x12, 0x50, 0x72, + 0x6f, 0x74, 0x6f, 0x41, 0x64, 0x64, 0x72, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x73, + 0x12, 0x1a, 0x0a, 0x08, 0x54, 0x6f, 0x74, 0x61, 0x6c, 0x54, 0x78, 0x73, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x04, 0x52, 0x08, 0x54, 0x6f, 0x74, 0x61, 0x6c, 0x54, 0x78, 0x73, 0x12, 0x26, 0x0a, 0x0e, + 0x4e, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x54, 0x78, 0x73, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x04, 0x52, 0x0e, 0x4e, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, + 0x74, 0x54, 0x78, 0x73, 0x12, 0x20, 0x0a, 0x0b, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, + 0x54, 0x78, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, 0x49, 0x6e, 0x74, 0x65, 0x72, + 0x6e, 0x61, 0x6c, 0x54, 0x78, 0x73, 0x12, 0x3e, 0x0a, 0x09, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x61, + 0x63, 0x74, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x50, 0x72, 0x6f, 0x74, + 0x6f, 0x41, 0x64, 0x64, 0x72, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x73, 0x2e, 0x41, + 0x64, 0x64, 0x72, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x52, 0x09, 0x43, 0x6f, 0x6e, + 0x74, 0x72, 0x61, 0x63, 0x74, 0x73, 0x1a, 0x37, 0x0a, 0x0f, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x54, + 0x6f, 0x6b, 0x65, 0x6e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x49, 0x64, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x02, 0x49, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x56, 0x61, 0x6c, + 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x1a, + 0xc9, 0x01, 0x0a, 0x0c, 0x41, 0x64, 0x64, 0x72, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, + 0x12, 0x12, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x04, + 0x54, 0x79, 0x70, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, + 0x12, 0x10, 0x0a, 0x03, 0x54, 0x78, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x03, 0x54, + 0x78, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x0c, 0x52, 0x05, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x49, 0x64, 0x73, 0x18, + 0x05, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x03, 0x49, 0x64, 0x73, 0x12, 0x4f, 0x0a, 0x10, 0x4d, 0x75, + 0x6c, 0x74, 0x69, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x18, 0x06, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x41, 0x64, 0x64, 0x72, + 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x73, 0x2e, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x54, + 0x6f, 0x6b, 0x65, 0x6e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x10, 0x4d, 0x75, 0x6c, 0x74, 0x69, + 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x42, 0x2e, 0x5a, 0x2c, 0x67, + 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x74, 0x72, 0x65, 0x7a, 0x6f, 0x72, + 0x2f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x62, 0x6f, 0x6f, 0x6b, 0x2f, 0x62, 0x63, 0x68, 0x61, 0x69, + 0x6e, 0x2f, 0x63, 0x6f, 0x69, 0x6e, 0x73, 0x2f, 0x65, 0x74, 0x68, 0x62, 0x06, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x33, +} + +var ( + file_bchain_coins_eth_ethaddrcontracts_proto_rawDescOnce sync.Once + file_bchain_coins_eth_ethaddrcontracts_proto_rawDescData = file_bchain_coins_eth_ethaddrcontracts_proto_rawDesc +) + +func file_bchain_coins_eth_ethaddrcontracts_proto_rawDescGZIP() []byte { + file_bchain_coins_eth_ethaddrcontracts_proto_rawDescOnce.Do(func() { + file_bchain_coins_eth_ethaddrcontracts_proto_rawDescData = protoimpl.X.CompressGZIP(file_bchain_coins_eth_ethaddrcontracts_proto_rawDescData) + }) + return file_bchain_coins_eth_ethaddrcontracts_proto_rawDescData +} + +var file_bchain_coins_eth_ethaddrcontracts_proto_msgTypes = make([]protoimpl.MessageInfo, 3) +var file_bchain_coins_eth_ethaddrcontracts_proto_goTypes = []interface{}{ + (*ProtoAddrContracts)(nil), // 0: ProtoAddrContracts + (*ProtoAddrContracts_MultiTokenValue)(nil), // 1: ProtoAddrContracts.MultiTokenValue + (*ProtoAddrContracts_AddrContract)(nil), // 2: ProtoAddrContracts.AddrContract +} +var file_bchain_coins_eth_ethaddrcontracts_proto_depIdxs = []int32{ + 2, // 0: ProtoAddrContracts.Contracts:type_name -> ProtoAddrContracts.AddrContract + 1, // 1: ProtoAddrContracts.AddrContract.MultiTokenValues:type_name -> ProtoAddrContracts.MultiTokenValue + 2, // [2:2] is the sub-list for method output_type + 2, // [2:2] is the sub-list for method input_type + 2, // [2:2] is the sub-list for extension type_name + 2, // [2:2] is the sub-list for extension extendee + 0, // [0:2] is the sub-list for field type_name +} + +func init() { file_bchain_coins_eth_ethaddrcontracts_proto_init() } +func file_bchain_coins_eth_ethaddrcontracts_proto_init() { + if File_bchain_coins_eth_ethaddrcontracts_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_bchain_coins_eth_ethaddrcontracts_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ProtoAddrContracts); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_bchain_coins_eth_ethaddrcontracts_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ProtoAddrContracts_MultiTokenValue); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_bchain_coins_eth_ethaddrcontracts_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ProtoAddrContracts_AddrContract); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_bchain_coins_eth_ethaddrcontracts_proto_rawDesc, + NumEnums: 0, + NumMessages: 3, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_bchain_coins_eth_ethaddrcontracts_proto_goTypes, + DependencyIndexes: file_bchain_coins_eth_ethaddrcontracts_proto_depIdxs, + MessageInfos: file_bchain_coins_eth_ethaddrcontracts_proto_msgTypes, + }.Build() + File_bchain_coins_eth_ethaddrcontracts_proto = out.File + file_bchain_coins_eth_ethaddrcontracts_proto_rawDesc = nil + file_bchain_coins_eth_ethaddrcontracts_proto_goTypes = nil + file_bchain_coins_eth_ethaddrcontracts_proto_depIdxs = nil +} diff --git a/bchain/coins/eth/ethaddrcontracts.proto b/bchain/coins/eth/ethaddrcontracts.proto new file mode 100644 index 0000000000..4402ba6fc7 --- /dev/null +++ b/bchain/coins/eth/ethaddrcontracts.proto @@ -0,0 +1,22 @@ +syntax = "proto3"; + +option go_package = "github.com/trezor/blockbook/bchain/coins/eth"; + +message ProtoAddrContracts { + message MultiTokenValue { + bytes Id = 1; + bytes Value = 2; + } + message AddrContract { + int64 Type = 1; + bytes Contract = 2; + uint64 Txs = 3; + bytes Value = 4; + repeated bytes Ids = 5; + repeated MultiTokenValue MultiTokenValues = 6; + } + uint64 TotalTxs = 1; + uint64 NonContractTxs = 2; + uint64 InternalTxs = 3; + repeated AddrContract Contracts = 4; +} \ No newline at end of file diff --git a/bchain/coins/eth/ethtx.pb.go b/bchain/coins/eth/ethtx.pb.go index 0174ab9b0a..83971a1a77 100644 --- a/bchain/coins/eth/ethtx.pb.go +++ b/bchain/coins/eth/ethtx.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.28.1 -// protoc v3.21.12 +// protoc-gen-go v1.33.0 +// protoc v4.25.3 // source: bchain/coins/eth/ethtx.proto package eth diff --git a/blockbook.go b/blockbook.go index 6675aec32d..8821dfd502 100644 --- a/blockbook.go +++ b/blockbook.go @@ -43,9 +43,10 @@ const exitCodeFatal = 255 var ( configFile = flag.String("blockchaincfg", "", "path to blockchain RPC service configuration json file") - dbPath = flag.String("datadir", "./data", "path to database directory") - dbCache = flag.Int("dbcache", 1<<29, "size of the rocksdb cache") - dbMaxOpenFiles = flag.Int("dbmaxopenfiles", 1<<14, "max open files by rocksdb") + dbPath = flag.String("datadir", "./data", "path to database directory") + dbCache = flag.Int("dbcache", 1<<29, "size of the rocksdb cache") + dbMaxOpenFiles = flag.Int("dbmaxopenfiles", 1<<14, "max open files by rocksdb") + dbMaxAddrContracts = flag.Int("dbmaxaddrcontracts", 1<<20, "max size of the address contracts map") blockFrom = flag.Int("blockheight", -1, "height of the starting block") blockUntil = flag.Int("blockuntil", -1, "height of the final block") @@ -169,7 +170,7 @@ func mainWithExitCode() int { return exitCodeFatal } - index, err = db.NewRocksDB(*dbPath, *dbCache, *dbMaxOpenFiles, chain.GetChainParser(), metrics, *extendedIndex) + index, err = db.NewRocksDB(*dbPath, *dbCache, *dbMaxOpenFiles, chain.GetChainParser(), metrics, *extendedIndex, *dbMaxAddrContracts) if err != nil { glog.Error("rocksDB: ", err) return exitCodeFatal diff --git a/configs/coins/base.json b/configs/coins/base.json new file mode 100644 index 0000000000..a3bf821b58 --- /dev/null +++ b/configs/coins/base.json @@ -0,0 +1,64 @@ +{ + "coin": { + "name": "Base", + "shortcut": "ETH", + "label": "Base", + "alias": "base" + }, + "ports": { + "backend_rpc": 8078, + "backend_p2p": 38378, + "backend_http": 8178, + "blockbook_internal": 9078, + "blockbook_public": 9178 + }, + "ipc": { + "rpc_url_template": "ws://127.0.0.1:{{.Ports.BackendRPC}}", + "rpc_timeout": 25 + }, + "backend": { + "package_name": "backend-base", + "package_revision": "satoshilabs-1", + "system_user": "base", + "version": "0.8.8", + "binary_url": "TODO", + "verification_type": "sha256", + "verification_source": "TODO", + "extract_command": "TODO", + "exclude_files": [], + "exec_command_template": "TODO", + "logrotate_files_template": "{{.Env.BackendDataPath}}/{{.Coin.Alias}}/backend/{{.Coin.Alias}}.log", + "postinst_script_template": "", + "service_type": "simple", + "service_additional_params_template": "", + "protect_memory": true, + "mainnet": true, + "server_config_file": "", + "client_config_file": "" + }, + "blockbook": { + "package_name": "blockbook-base", + "system_user": "blockbook-base", + "internal_binding_template": ":{{.Ports.BlockbookInternal}}", + "public_binding_template": ":{{.Ports.BlockbookPublic}}", + "explorer_url": "", + "additional_params": "", + "block_chain": { + "parse": true, + "mempool_workers": 8, + "mempool_sub_workers": 2, + "block_addresses_to_keep": 300, + "additional_params": { + "mempoolTxTimeoutHours": 48, + "queryBackendOnMempoolResync": false, + "fiat_rates": "coingecko", + "fiat_rates_vs_currencies": "AED,ARS,AUD,BDT,BHD,BMD,BRL,CAD,CHF,CLP,CNY,CZK,DKK,EUR,GBP,HKD,HUF,IDR,ILS,INR,JPY,KRW,KWD,LKR,MMK,MXN,MYR,NGN,NOK,NZD,PHP,PKR,PLN,RUB,SAR,SEK,SGD,THB,TRY,TWD,UAH,USD,VEF,VND,ZAR,BTC,ETH", + "fiat_rates_params": "{\"coin\": \"base\",\"platformIdentifier\": \"base\",\"platformVsCurrency\": \"eth\",\"periodSeconds\": 900}" + } + } + }, + "meta": { + "package_maintainer": "IT", + "package_maintainer_email": "it@satoshilabs.com" + } +} diff --git a/db/bulkconnect.go b/db/bulkconnect.go index 8c2095bf7e..bac2b75bd0 100644 --- a/db/bulkconnect.go +++ b/db/bulkconnect.go @@ -29,30 +29,26 @@ type BulkConnect struct { txAddressesMap map[string]*TxAddresses blockFilters map[string][]byte balances map[string]*AddrBalance - addressContracts map[string]*AddrContracts height uint32 } const ( - maxBulkAddresses = 80000 - maxBulkTxAddresses = 500000 - partialStoreAddresses = maxBulkTxAddresses / 10 - maxBulkBalances = 700000 - partialStoreBalances = maxBulkBalances / 10 - maxBulkAddrContracts = 1200000 - partialStoreAddrContracts = maxBulkAddrContracts / 10 - maxBlockFilters = 1000 + maxBulkAddresses = 80000 + maxBulkTxAddresses = 500000 + partialStoreAddresses = maxBulkTxAddresses / 10 + maxBulkBalances = 700000 + partialStoreBalances = maxBulkBalances / 10 + maxBlockFilters = 1000 ) // InitBulkConnect initializes bulk connect and switches DB to inconsistent state func (d *RocksDB) InitBulkConnect() (*BulkConnect, error) { b := &BulkConnect{ - d: d, - chainType: d.chainParser.GetChainType(), - txAddressesMap: make(map[string]*TxAddresses), - balances: make(map[string]*AddrBalance), - addressContracts: make(map[string]*AddrContracts), - blockFilters: make(map[string][]byte), + d: d, + chainType: d.chainParser.GetChainType(), + txAddressesMap: make(map[string]*TxAddresses), + balances: make(map[string]*AddrBalance), + blockFilters: make(map[string][]byte), } if err := d.SetInconsistentState(true); err != nil { return nil, err @@ -266,15 +262,15 @@ func (b *BulkConnect) connectBlockBitcoinType(block *bchain.Block, storeBlockTxs func (b *BulkConnect) storeAddressContracts(wb *grocksdb.WriteBatch, all bool) (int, error) { var ac map[string]*AddrContracts if all { - ac = b.addressContracts - b.addressContracts = make(map[string]*AddrContracts) + ac = b.d.addressContracts + b.d.addressContracts = make(map[string]*AddrContracts) } else { ac = make(map[string]*AddrContracts) // store some random address contracts - for k, a := range b.addressContracts { + for k, a := range b.d.addressContracts { ac[k] = a - delete(b.addressContracts, k) - if len(ac) >= partialStoreAddrContracts { + delete(b.d.addressContracts, k) + if len(ac) >= (b.d.maxAddrContracts / 10) { break } } @@ -299,20 +295,20 @@ func (b *BulkConnect) parallelStoreAddressContracts(c chan error, all bool) { c <- err return } - glog.Info("rocksdb: height ", b.height, ", stored ", count, " addressContracts, ", len(b.addressContracts), " remaining, done in ", time.Since(start)) + glog.Info("rocksdb: height ", b.height, ", stored ", count, " addressContracts, ", len(b.d.addressContracts), " remaining, done in ", time.Since(start)) c <- nil } func (b *BulkConnect) connectBlockEthereumType(block *bchain.Block, storeBlockTxs bool) error { addresses := make(addressesMap) - blockTxs, err := b.d.processAddressesEthereumType(block, addresses, b.addressContracts) + blockTxs, err := b.d.processAddressesEthereumType(block, addresses, b.d.addressContracts) if err != nil { return err } b.ethBlockTxs = append(b.ethBlockTxs, blockTxs...) var storeAddrContracts chan error var sa bool - if len(b.addressContracts) > maxBulkAddrContracts { + if len(b.d.addressContracts) > b.d.maxAddrContracts { sa = true storeAddrContracts = make(chan error) go b.parallelStoreAddressContracts(storeAddrContracts, false) diff --git a/db/rocksdb.go b/db/rocksdb.go index 58e269d743..5a07ec556b 100644 --- a/db/rocksdb.go +++ b/db/rocksdb.go @@ -5,6 +5,7 @@ import ( "encoding/binary" "encoding/hex" "fmt" + "math" "math/big" "os" "path/filepath" @@ -59,18 +60,20 @@ const ( // RocksDB handle type RocksDB struct { - path string - db *grocksdb.DB - wo *grocksdb.WriteOptions - ro *grocksdb.ReadOptions - cfh []*grocksdb.ColumnFamilyHandle - chainParser bchain.BlockChainParser - is *common.InternalState - metrics *common.Metrics - cache *grocksdb.Cache - maxOpenFiles int - cbs connectBlockStats - extendedIndex bool + path string + db *grocksdb.DB + wo *grocksdb.WriteOptions + ro *grocksdb.ReadOptions + cfh []*grocksdb.ColumnFamilyHandle + chainParser bchain.BlockChainParser + is *common.InternalState + metrics *common.Metrics + cache *grocksdb.Cache + maxOpenFiles int + cbs connectBlockStats + extendedIndex bool + maxAddrContracts int + addressContracts map[string]*AddrContracts } const ( @@ -128,7 +131,7 @@ func openDB(path string, c *grocksdb.Cache, openFiles int) (*grocksdb.DB, []*gro // NewRocksDB opens an internal handle to RocksDB environment. Close // needs to be called to release it. -func NewRocksDB(path string, cacheSize, maxOpenFiles int, parser bchain.BlockChainParser, metrics *common.Metrics, extendedIndex bool) (d *RocksDB, err error) { +func NewRocksDB(path string, cacheSize, maxOpenFiles int, parser bchain.BlockChainParser, metrics *common.Metrics, extendedIndex bool, maxAddrContracts int) (*RocksDB, error) { glog.Infof("rocksdb: opening %s, required data version %v, cache size %v, max open files %v", path, dbVersion, cacheSize, maxOpenFiles) cfNames = append([]string{}, cfBaseNames...) @@ -147,9 +150,23 @@ func NewRocksDB(path string, cacheSize, maxOpenFiles int, parser bchain.BlockCha if err != nil { return nil, err } - wo := grocksdb.NewDefaultWriteOptions() - ro := grocksdb.NewDefaultReadOptions() - return &RocksDB{path, db, wo, ro, cfh, parser, nil, metrics, c, maxOpenFiles, connectBlockStats{}, extendedIndex}, nil + d := &RocksDB{ + path: path, + db: db, + wo: grocksdb.NewDefaultWriteOptions(), + ro: grocksdb.NewDefaultReadOptions(), + cfh: cfh, + chainParser: parser, + is: nil, + metrics: metrics, + cache: c, + maxOpenFiles: maxOpenFiles, + cbs: connectBlockStats{}, + extendedIndex: extendedIndex, + maxAddrContracts: maxAddrContracts, + addressContracts: make(map[string]*AddrContracts), + } + return d, nil } func (d *RocksDB) closeDB() error { @@ -331,6 +348,22 @@ const ( opDelete = 1 ) +func (d *RocksDB) pruneAddressContracts(attempt float64) { + desiredSize := d.maxAddrContracts / 2 + threshold := math.Pow(10, attempt) + for k, v := range d.addressContracts { + if len(d.addressContracts) == desiredSize { + break + } + if len(v.Contracts) < int(threshold) { + delete(d.addressContracts, k) + } + } + if len(d.addressContracts) > desiredSize { + d.pruneAddressContracts(attempt + 1) + } +} + // ConnectBlock indexes addresses in the block and stores them in db func (d *RocksDB) ConnectBlock(block *bchain.Block) error { wb := grocksdb.NewWriteBatch() @@ -375,6 +408,9 @@ func (d *RocksDB) ConnectBlock(block *bchain.Block) error { } } } else if chainType == bchain.ChainEthereumType { + if len(d.addressContracts) > d.maxAddrContracts { + d.pruneAddressContracts(1) + } addressContracts := make(map[string]*AddrContracts) blockTxs, err := d.processAddressesEthereumType(block, addresses, addressContracts) if err != nil { diff --git a/db/rocksdb_ethereumtype.go b/db/rocksdb_ethereumtype.go index 11371a7914..f16ca6d6e4 100644 --- a/db/rocksdb_ethereumtype.go +++ b/db/rocksdb_ethereumtype.go @@ -14,6 +14,7 @@ import ( "github.com/linxGnu/grocksdb" "github.com/trezor/blockbook/bchain" "github.com/trezor/blockbook/bchain/coins/eth" + "google.golang.org/protobuf/proto" ) const InternalTxIndexOffset = 1 @@ -124,45 +125,79 @@ type AddrContracts struct { Contracts []AddrContract } -// packAddrContracts packs AddrContracts into a byte buffer -func packAddrContracts(acs *AddrContracts) []byte { - buf := make([]byte, 0, 128) - varBuf := make([]byte, maxPackedBigintBytes) - l := packVaruint(acs.TotalTxs, varBuf) - buf = append(buf, varBuf[:l]...) - l = packVaruint(acs.NonContractTxs, varBuf) - buf = append(buf, varBuf[:l]...) - l = packVaruint(acs.InternalTxs, varBuf) - buf = append(buf, varBuf[:l]...) - for _, ac := range acs.Contracts { - buf = append(buf, ac.Contract...) - l = packVaruint(uint(ac.Type)+ac.Txs<<2, varBuf) - buf = append(buf, varBuf[:l]...) - if ac.Type == bchain.FungibleToken { - l = packBigint(&ac.Value, varBuf) - buf = append(buf, varBuf[:l]...) - } else if ac.Type == bchain.NonFungibleToken { - l = packVaruint(uint(len(ac.Ids)), varBuf) - buf = append(buf, varBuf[:l]...) - for i := range ac.Ids { - l = packBigint(&ac.Ids[i], varBuf) - buf = append(buf, varBuf[:l]...) - } - } else { // bchain.ERC1155 - l = packVaruint(uint(len(ac.MultiTokenValues)), varBuf) - buf = append(buf, varBuf[:l]...) - for i := range ac.MultiTokenValues { - l = packBigint(&ac.MultiTokenValues[i].Id, varBuf) - buf = append(buf, varBuf[:l]...) - l = packBigint(&ac.MultiTokenValues[i].Value, varBuf) - buf = append(buf, varBuf[:l]...) +// packAddrContract packs AddrContracts into a protobuf encoded byte slice +func packAddrContracts(acs *AddrContracts) ([]byte, error) { + ptContracts := make([]*eth.ProtoAddrContracts_AddrContract, len(acs.Contracts)) + for i, c := range acs.Contracts { + ptIds := make([][]byte, len(c.Ids)) + for j, id := range c.Ids { + ptIds[j] = id.Bytes() + } + ptMultiTokenValues := make([]*eth.ProtoAddrContracts_MultiTokenValue, len(c.MultiTokenValues)) + for k, mtv := range c.MultiTokenValues { + ptMultiTokenValues[k] = ð.ProtoAddrContracts_MultiTokenValue{ + Id: mtv.Id.Bytes(), + Value: mtv.Value.Bytes(), } } + ptContracts[i] = ð.ProtoAddrContracts_AddrContract{ + Contract: c.Contract, + Ids: ptIds, + MultiTokenValues: ptMultiTokenValues, + Type: int64(c.Type), + Txs: uint64(c.Txs), + Value: c.Value.Bytes(), + } } - return buf + pt := ð.ProtoAddrContracts{ + TotalTxs: uint64(acs.TotalTxs), + InternalTxs: uint64(acs.InternalTxs), + NonContractTxs: uint64(acs.NonContractTxs), + Contracts: ptContracts, + } + return proto.Marshal(pt) } +// unpackAddrContract unpacks the protobuf encoded byte slice into AddrContracts func unpackAddrContracts(buf []byte, addrDesc bchain.AddressDescriptor) (*AddrContracts, error) { + pt := ð.ProtoAddrContracts{} + err := proto.Unmarshal(buf, pt) + if err != nil { + return unpackAddrContractsLegacy(buf, addrDesc) + } + contracts := make([]AddrContract, len(pt.Contracts)) + for i, c := range pt.Contracts { + ids := make([]big.Int, len(c.Ids)) + for j, id := range c.Ids { + ids[j] = *new(big.Int).SetBytes(id) + } + multiTokenValues := make(MultiTokenValues, len(c.MultiTokenValues)) + for k, mtv := range c.MultiTokenValues { + multiTokenValues[k] = bchain.MultiTokenValue{ + Id: *new(big.Int).SetBytes(mtv.Id), + Value: *new(big.Int).SetBytes(mtv.Value), + } + } + contracts[i] = AddrContract{ + Type: bchain.TokenType(c.Type), + Contract: c.Contract, + Txs: uint(c.Txs), + Value: *new(big.Int).SetBytes(c.Value), + Ids: ids, + MultiTokenValues: multiTokenValues, + } + } + acs := &AddrContracts{ + TotalTxs: uint(pt.TotalTxs), + NonContractTxs: uint(pt.NonContractTxs), + InternalTxs: uint(pt.InternalTxs), + Contracts: contracts, + } + return acs, nil +} + +// unpackAddrContractsLegacy unpacks AddrContracts from legacy manual packed byte slice +func unpackAddrContractsLegacy(buf []byte, addrDesc bchain.AddressDescriptor) (*AddrContracts, error) { tt, l := unpackVaruint(buf) buf = buf[l:] nct, l := unpackVaruint(buf) @@ -226,7 +261,10 @@ func (d *RocksDB) storeAddressContracts(wb *grocksdb.WriteBatch, acm map[string] if acs == nil || (acs.NonContractTxs == 0 && acs.InternalTxs == 0 && len(acs.Contracts) == 0) { wb.DeleteCF(d.cfh[cfAddressContracts], bchain.AddressDescriptor(addrDesc)) } else { - buf := packAddrContracts(acs) + buf, err := packAddrContracts(acs) + if err != nil { + return err + } wb.PutCF(d.cfh[cfAddressContracts], bchain.AddressDescriptor(addrDesc), buf) } } @@ -338,7 +376,7 @@ func addToContract(c *AddrContract, contractIndex int, index int32, contract bch func (d *RocksDB) addToAddressesAndContractsEthereumType(addrDesc bchain.AddressDescriptor, btxID []byte, index int32, contract bchain.AddressDescriptor, transfer *bchain.TokenTransfer, addTxCount bool, addresses addressesMap, addressContracts map[string]*AddrContracts) error { var err error strAddrDesc := string(addrDesc) - ac, e := addressContracts[strAddrDesc] + ac, e := d.addressContracts[strAddrDesc] if !e { ac, err = d.GetAddrDescContracts(addrDesc) if err != nil { @@ -348,8 +386,10 @@ func (d *RocksDB) addToAddressesAndContractsEthereumType(addrDesc bchain.Address ac = &AddrContracts{} } addressContracts[strAddrDesc] = ac + d.addressContracts[strAddrDesc] = ac d.cbs.balancesMiss++ } else { + addressContracts[strAddrDesc] = ac d.cbs.balancesHit++ } if contract == nil { @@ -1438,7 +1478,10 @@ func (d *RocksDB) SortAddressContracts(stop chan os.Signal) error { if err := func() error { wb := grocksdb.NewWriteBatch() defer wb.Destroy() - buf := packAddrContracts(ca) + buf, err := packAddrContracts(ca) + if err != nil { + return err + } wb.PutCF(d.cfh[cfAddressContracts], addrDesc, buf) return d.WriteBatch(wb) }(); err != nil { From e534fb3b1bed8e24f3147714d17488e1e0475c92 Mon Sep 17 00:00:00 2001 From: kaladinlight <35275952+kaladinlight@users.noreply.github.com> Date: Mon, 4 Nov 2024 11:44:46 -0700 Subject: [PATCH 02/13] backend config --- bchain/coins/base/baserpc.go | 12 +--- build/templates/backend/scripts/base.sh | 45 ++++++++++++ .../templates/backend/scripts/base_archive.sh | 47 +++++++++++++ .../backend/scripts/base_archive_op_node.sh | 24 +++++++ .../templates/backend/scripts/base_op_node.sh | 24 +++++++ configs/coins/base.json | 30 ++++---- configs/coins/base_archive.json | 69 +++++++++++++++++++ configs/coins/base_archive_op_node.json | 38 ++++++++++ configs/coins/base_op_node.json | 38 ++++++++++ docs/ports.md | 4 +- 10 files changed, 305 insertions(+), 26 deletions(-) create mode 100644 build/templates/backend/scripts/base.sh create mode 100644 build/templates/backend/scripts/base_archive.sh create mode 100644 build/templates/backend/scripts/base_archive_op_node.sh create mode 100644 build/templates/backend/scripts/base_op_node.sh create mode 100644 configs/coins/base_archive.json create mode 100644 configs/coins/base_archive_op_node.json create mode 100644 configs/coins/base_op_node.json diff --git a/bchain/coins/base/baserpc.go b/bchain/coins/base/baserpc.go index fecf9327a5..116f82efa6 100644 --- a/bchain/coins/base/baserpc.go +++ b/bchain/coins/base/baserpc.go @@ -4,8 +4,6 @@ import ( "context" "encoding/json" - "github.com/ethereum/go-ethereum/ethclient" - "github.com/ethereum/go-ethereum/rpc" "github.com/golang/glog" "github.com/juju/errors" "github.com/trezor/blockbook/bchain" @@ -38,15 +36,7 @@ func NewBaseRPC(config json.RawMessage, pushHandler func(bchain.NotificationType // Initialize base rpc interface func (b *BaseRPC) Initialize() error { - b.OpenRPC = func(url string) (bchain.EVMRPCClient, bchain.EVMClient, error) { - r, err := rpc.Dial(url) - if err != nil { - return nil, nil, err - } - rc := ð.EthereumRPCClient{Client: r} - ec := ð.EthereumClient{Client: ethclient.NewClient(r)} - return rc, ec, nil - } + b.OpenRPC = eth.OpenRPC rc, ec, err := b.OpenRPC(b.ChainConfig.RPCURL) if err != nil { diff --git a/build/templates/backend/scripts/base.sh b/build/templates/backend/scripts/base.sh new file mode 100644 index 0000000000..1b9305644b --- /dev/null +++ b/build/templates/backend/scripts/base.sh @@ -0,0 +1,45 @@ +#!/bin/sh + +{{define "main" -}} + +set -e + +GETH_BIN={{.Env.BackendInstallPath}}/{{.Coin.Alias}}/geth +DATA_DIR={{.Env.BackendDataPath}}/{{.Coin.Alias}}/backend + +CHAINDATA_DIR=$DATA_DIR/geth/chaindata +SNAPSHOT=https://mainnet-full-snapshots.base.org/$(curl https://mainnet-full-snapshots.base.org/latest) + +if [ ! -d "$CHAINDATA_DIR" ]; then + wget -c $SNAPSHOT -O - | zstd -cd | tar xf - --strip-components=1 -C $DATA_DIR +fi + +$GETH_BIN \ + --op-network base-mainnet \ + --datadir $DATA_DIR \ + --authrpc.jwtsecret $DATA_DIR/jwtsecret \ + --authrpc.addr 127.0.0.1 \ + --authrpc.port {{.Ports.BackendAuthRpc}} \ + --authrpc.vhosts "*" \ + --port {{.Ports.BackendP2P}} \ + --http \ + --http.port {{.Ports.BackendHttp}} \ + --http.addr 127.0.0.1 \ + --http.api eth,net,web3,debug,txpool,engine \ + --http.vhosts "*" \ + --http.corsdomain "*" \ + --ws \ + --ws.port {{.Ports.BackendRPC}} \ + --ws.addr 127.0.0.1 \ + --ws.api eth,net,web3,debug,txpool,engine \ + --ws.origins "*" \ + --rollup.disabletxpoolgossip=true \ + --rollup.sequencerhttp https://mainnet-sequencer.base.io \ + --state.scheme hash \ + --history.transactions 0 \ + --cache 4096 \ + --syncmode full \ + --maxpeers 0 \ + --nodiscover + +{{end}} diff --git a/build/templates/backend/scripts/base_archive.sh b/build/templates/backend/scripts/base_archive.sh new file mode 100644 index 0000000000..a4bf1444fe --- /dev/null +++ b/build/templates/backend/scripts/base_archive.sh @@ -0,0 +1,47 @@ +#!/bin/sh + +{{define "main" -}} + +set -e + +GETH_BIN={{.Env.BackendInstallPath}}/{{.Coin.Alias}}/geth +DATA_DIR={{.Env.BackendDataPath}}/{{.Coin.Alias}}/backend + +CHAINDATA_DIR=$DATA_DIR/geth/chaindata +SNAPSHOT=https://mainnet-archive-snapshots.base.org/$(curl https://mainnet-archive-snapshots.base.org/latest) + +if [ ! -d "$CHAINDATA_DIR" ]; then + wget -c $SNAPSHOT -O - | zstd -cd | tar xf - --strip-components=1 -C $DATA_DIR +fi + +$GETH_BIN \ + --op-network base-mainnet \ + --datadir $DATA_DIR \ + --authrpc.jwtsecret $DATA_DIR/jwtsecret \ + --authrpc.addr 127.0.0.1 \ + --authrpc.port {{.Ports.BackendAuthRpc}} \ + --authrpc.vhosts "*" \ + --port {{.Ports.BackendP2P}} \ + --http \ + --http.port {{.Ports.BackendHttp}} \ + --http.addr 127.0.0.1 \ + --http.api eth,net,web3,debug,txpool,engine \ + --http.vhosts "*" \ + --http.corsdomain "*" \ + --ws \ + --ws.port {{.Ports.BackendRPC}} \ + --ws.addr 127.0.0.1 \ + --ws.api eth,net,web3,debug,txpool,engine \ + --ws.origins "*" \ + --rollup.disabletxpoolgossip=true \ + --rollup.sequencerhttp https://mainnet.sequencer.optimism.io \ + --cache 4096 \ + --cache.gc 0 \ + --cache.trie 30 \ + --cache.snapshot 20 \ + --syncmode full \ + --gcmode archive \ + --maxpeers 0 \ + --nodiscover + +{{end}} diff --git a/build/templates/backend/scripts/base_archive_op_node.sh b/build/templates/backend/scripts/base_archive_op_node.sh new file mode 100644 index 0000000000..75e122da8e --- /dev/null +++ b/build/templates/backend/scripts/base_archive_op_node.sh @@ -0,0 +1,24 @@ +#!/bin/sh + +{{define "main" -}} + +set -e + +BIN={{.Env.BackendInstallPath}}/{{.Coin.Alias}}/op-node + +$BIN \ + --network base-mainnet \ + --l1 http://127.0.0.1:8116 \ + --l1.beacon http://127.0.0.1:7516 \ + --l1.trustrpc \ + --l1.rpckind=debug_geth \ + --l2 http://127.0.0.1:8411 \ + --rpc.addr 127.0.0.1 \ + --rpc.port {{.Ports.BackendRPC}} \ + --l2.jwt-secret {{.Env.BackendDataPath}}/base_archive/backend/jwtsecret \ + --p2p.bootnodes enr:-J24QNz9lbrKbN4iSmmjtnr7SjUMk4zB7f1krHZcTZx-JRKZd0kA2gjufUROD6T3sOWDVDnFJRvqBBo62zuF-hYCohOGAYiOoEyEgmlkgnY0gmlwhAPniryHb3BzdGFja4OFQgCJc2VjcDI1NmsxoQKNVFlCxh_B-716tTs-h1vMzZkSs1FTu_OYTNjgufplG4N0Y3CCJAaDdWRwgiQG,enr:-J24QH-f1wt99sfpHy4c0QJM-NfmsIfmlLAMMcgZCUEgKG_BBYFc6FwYgaMJMQN5dsRBJApIok0jFn-9CS842lGpLmqGAYiOoDRAgmlkgnY0gmlwhLhIgb2Hb3BzdGFja4OFQgCJc2VjcDI1NmsxoQJ9FTIv8B9myn1MWaC_2lJ-sMoeCDkusCsk4BYHjjCq04N0Y3CCJAaDdWRwgiQG,enr:-J24QDXyyxvQYsd0yfsN0cRr1lZ1N11zGTplMNlW4xNEc7LkPXh0NAJ9iSOVdRO95GPYAIc6xmyoCCG6_0JxdL3a0zaGAYiOoAjFgmlkgnY0gmlwhAPckbGHb3BzdGFja4OFQgCJc2VjcDI1NmsxoQJwoS7tzwxqXSyFL7g0JM-KWVbgvjfB8JA__T7yY_cYboN0Y3CCJAaDdWRwgiQG,enr:-J24QHmGyBwUZXIcsGYMaUqGGSl4CFdx9Tozu-vQCn5bHIQbR7On7dZbU61vYvfrJr30t0iahSqhc64J46MnUO2JvQaGAYiOoCKKgmlkgnY0gmlwhAPnCzSHb3BzdGFja4OFQgCJc2VjcDI1NmsxoQINc4fSijfbNIiGhcgvwjsjxVFJHUstK9L1T8OTKUjgloN0Y3CCJAaDdWRwgiQG,enr:-J24QG3ypT4xSu0gjb5PABCmVxZqBjVw9ca7pvsI8jl4KATYAnxBmfkaIuEqy9sKvDHKuNCsy57WwK9wTt2aQgcaDDyGAYiOoGAXgmlkgnY0gmlwhDbGmZaHb3BzdGFja4OFQgCJc2VjcDI1NmsxoQIeAK_--tcLEiu7HvoUlbV52MspE0uCocsx1f_rYvRenIN0Y3CCJAaDdWRwgiQG \ + --p2p.useragent base \ + --rollup.load-protocol-versions=true \ + --verifier.l1-confs 4 + +{{end}} diff --git a/build/templates/backend/scripts/base_op_node.sh b/build/templates/backend/scripts/base_op_node.sh new file mode 100644 index 0000000000..4254b8972e --- /dev/null +++ b/build/templates/backend/scripts/base_op_node.sh @@ -0,0 +1,24 @@ +#!/bin/sh + +{{define "main" -}} + +set -e + +BIN={{.Env.BackendInstallPath}}/{{.Coin.Alias}}/op-node + +$BIN \ + --network base-mainnet \ + --l1 http://127.0.0.1:8136 \ + --l1.beacon http://127.0.0.1:7536 \ + --l1.trustrpc \ + --l1.rpckind debug_geth \ + --l2 http://127.0.0.1:8409 \ + --rpc.addr 127.0.0.1 \ + --rpc.port {{.Ports.BackendRPC}} \ + --l2.jwt-secret {{.Env.BackendDataPath}}/base/backend/jwtsecret \ + --p2p.bootnodes enr:-J24QNz9lbrKbN4iSmmjtnr7SjUMk4zB7f1krHZcTZx-JRKZd0kA2gjufUROD6T3sOWDVDnFJRvqBBo62zuF-hYCohOGAYiOoEyEgmlkgnY0gmlwhAPniryHb3BzdGFja4OFQgCJc2VjcDI1NmsxoQKNVFlCxh_B-716tTs-h1vMzZkSs1FTu_OYTNjgufplG4N0Y3CCJAaDdWRwgiQG,enr:-J24QH-f1wt99sfpHy4c0QJM-NfmsIfmlLAMMcgZCUEgKG_BBYFc6FwYgaMJMQN5dsRBJApIok0jFn-9CS842lGpLmqGAYiOoDRAgmlkgnY0gmlwhLhIgb2Hb3BzdGFja4OFQgCJc2VjcDI1NmsxoQJ9FTIv8B9myn1MWaC_2lJ-sMoeCDkusCsk4BYHjjCq04N0Y3CCJAaDdWRwgiQG,enr:-J24QDXyyxvQYsd0yfsN0cRr1lZ1N11zGTplMNlW4xNEc7LkPXh0NAJ9iSOVdRO95GPYAIc6xmyoCCG6_0JxdL3a0zaGAYiOoAjFgmlkgnY0gmlwhAPckbGHb3BzdGFja4OFQgCJc2VjcDI1NmsxoQJwoS7tzwxqXSyFL7g0JM-KWVbgvjfB8JA__T7yY_cYboN0Y3CCJAaDdWRwgiQG,enr:-J24QHmGyBwUZXIcsGYMaUqGGSl4CFdx9Tozu-vQCn5bHIQbR7On7dZbU61vYvfrJr30t0iahSqhc64J46MnUO2JvQaGAYiOoCKKgmlkgnY0gmlwhAPnCzSHb3BzdGFja4OFQgCJc2VjcDI1NmsxoQINc4fSijfbNIiGhcgvwjsjxVFJHUstK9L1T8OTKUjgloN0Y3CCJAaDdWRwgiQG,enr:-J24QG3ypT4xSu0gjb5PABCmVxZqBjVw9ca7pvsI8jl4KATYAnxBmfkaIuEqy9sKvDHKuNCsy57WwK9wTt2aQgcaDDyGAYiOoGAXgmlkgnY0gmlwhDbGmZaHb3BzdGFja4OFQgCJc2VjcDI1NmsxoQIeAK_--tcLEiu7HvoUlbV52MspE0uCocsx1f_rYvRenIN0Y3CCJAaDdWRwgiQG \ + --p2p.useragent base \ + --rollup.load-protocol-versions=true \ + --verifier.l1-confs 4 + +{{end}} diff --git a/configs/coins/base.json b/configs/coins/base.json index a3bf821b58..1c148b0666 100644 --- a/configs/coins/base.json +++ b/configs/coins/base.json @@ -6,11 +6,12 @@ "alias": "base" }, "ports": { - "backend_rpc": 8078, - "backend_p2p": 38378, - "backend_http": 8178, - "blockbook_internal": 9078, - "blockbook_public": 9178 + "backend_rpc": 8309, + "backend_p2p": 38409, + "backend_http": 8209, + "backend_authrpc": 8409, + "blockbook_internal": 9209, + "blockbook_public": 9309 }, "ipc": { "rpc_url_template": "ws://127.0.0.1:{{.Ports.BackendRPC}}", @@ -20,15 +21,16 @@ "package_name": "backend-base", "package_revision": "satoshilabs-1", "system_user": "base", - "version": "0.8.8", - "binary_url": "TODO", - "verification_type": "sha256", - "verification_source": "TODO", - "extract_command": "TODO", + "version": "1.101411.0", + "docker_image": "us-docker.pkg.dev/oplabs-tools-artifacts/images/op-geth:v1.101411.0", + "verification_type": "docker", + "verification_source": "67f2c6fa24a0d12b0f8b5e251d4f40911baf5229532a06a877749a5a2d9506ff", + "extract_command": "docker cp extract:/usr/local/bin/geth backend/geth", "exclude_files": [], - "exec_command_template": "TODO", + "exec_command_template": "/bin/sh -c '{{.Env.BackendInstallPath}}/{{.Coin.Alias}}/base_exec.sh 2>> {{.Env.BackendDataPath}}/{{.Coin.Alias}}/backend/{{.Coin.Alias}}.log'", + "exec_script": "base.sh", "logrotate_files_template": "{{.Env.BackendDataPath}}/{{.Coin.Alias}}/backend/{{.Coin.Alias}}.log", - "postinst_script_template": "", + "postinst_script_template": "openssl rand -hex 32 > {{.Env.BackendDataPath}}/{{.Coin.Alias}}/backend/jwtsecret", "service_type": "simple", "service_additional_params_template": "", "protect_memory": true, @@ -53,7 +55,7 @@ "queryBackendOnMempoolResync": false, "fiat_rates": "coingecko", "fiat_rates_vs_currencies": "AED,ARS,AUD,BDT,BHD,BMD,BRL,CAD,CHF,CLP,CNY,CZK,DKK,EUR,GBP,HKD,HUF,IDR,ILS,INR,JPY,KRW,KWD,LKR,MMK,MXN,MYR,NGN,NOK,NZD,PHP,PKR,PLN,RUB,SAR,SEK,SGD,THB,TRY,TWD,UAH,USD,VEF,VND,ZAR,BTC,ETH", - "fiat_rates_params": "{\"coin\": \"base\",\"platformIdentifier\": \"base\",\"platformVsCurrency\": \"eth\",\"periodSeconds\": 900}" + "fiat_rates_params": "{\"url\": \"https://api.coingecko.com/api/v3\", \"coin\": \"ethereum\",\"platformIdentifier\": \"ethereum\",\"platformVsCurrency\": \"eth\",\"periodSeconds\": 900}" } } }, @@ -61,4 +63,4 @@ "package_maintainer": "IT", "package_maintainer_email": "it@satoshilabs.com" } -} +} \ No newline at end of file diff --git a/configs/coins/base_archive.json b/configs/coins/base_archive.json new file mode 100644 index 0000000000..735780e0d5 --- /dev/null +++ b/configs/coins/base_archive.json @@ -0,0 +1,69 @@ +{ + "coin": { + "name": "Base Archive", + "shortcut": "ETH", + "label": "Base", + "alias": "base_archive" + }, + "ports": { + "backend_rpc": 8211, + "backend_p2p": 38411, + "backend_http": 8311, + "backend_authrpc": 8411, + "blockbook_internal": 9211, + "blockbook_public": 9311 + }, + "ipc": { + "rpc_url_template": "ws://127.0.0.1:{{.Ports.BackendRPC}}", + "rpc_timeout": 25 + }, + "backend": { + "package_name": "backend-base-archive", + "package_revision": "satoshilabs-1", + "system_user": "base", + "version": "1.101411.0", + "docker_image": "us-docker.pkg.dev/oplabs-tools-artifacts/images/op-geth:v1.101411.0", + "verification_type": "docker", + "verification_source": "67f2c6fa24a0d12b0f8b5e251d4f40911baf5229532a06a877749a5a2d9506ff", + "extract_command": "docker cp extract:/usr/local/bin/geth backend/geth", + "exclude_files": [], + "exec_command_template": "/bin/sh -c '{{.Env.BackendInstallPath}}/{{.Coin.Alias}}/base_archive_exec.sh 2>> {{.Env.BackendDataPath}}/{{.Coin.Alias}}/backend/{{.Coin.Alias}}.log'", + "exec_script": "base_archive.sh", + "logrotate_files_template": "{{.Env.BackendDataPath}}/{{.Coin.Alias}}/backend/{{.Coin.Alias}}.log", + "postinst_script_template": "openssl rand -hex 32 > {{.Env.BackendDataPath}}/{{.Coin.Alias}}/backend/jwtsecret", + "service_type": "simple", + "service_additional_params_template": "", + "protect_memory": true, + "mainnet": true, + "server_config_file": "", + "client_config_file": "" + }, + "blockbook": { + "package_name": "blockbook-base-archive", + "system_user": "blockbook-base", + "internal_binding_template": ":{{.Ports.BlockbookInternal}}", + "public_binding_template": ":{{.Ports.BlockbookPublic}}", + "explorer_url": "", + "additional_params": "-workers=16", + "block_chain": { + "parse": true, + "mempool_workers": 8, + "mempool_sub_workers": 2, + "block_addresses_to_keep": 600, + "additional_params": { + "address_aliases": true, + "mempoolTxTimeoutHours": 48, + "processInternalTransactions": true, + "queryBackendOnMempoolResync": false, + "fiat_rates": "coingecko", + "fiat_rates_vs_currencies": "AED,ARS,AUD,BDT,BHD,BMD,BRL,CAD,CHF,CLP,CNY,CZK,DKK,EUR,GBP,HKD,HUF,IDR,ILS,INR,JPY,KRW,KWD,LKR,MMK,MXN,MYR,NGN,NOK,NZD,PHP,PKR,PLN,RUB,SAR,SEK,SGD,THB,TRY,TWD,UAH,USD,VEF,VND,ZAR,BTC,ETH", + "fiat_rates_params": "{\"url\": \"https://api.coingecko.com/api/v3\", \"coin\": \"ethereum\",\"platformIdentifier\": \"ethereum\",\"platformVsCurrency\": \"eth\",\"periodSeconds\": 900}", + "fourByteSignatures": "https://www.4byte.directory/api/v1/signatures/" + } + } + }, + "meta": { + "package_maintainer": "IT", + "package_maintainer_email": "it@satoshilabs.com" + } +} diff --git a/configs/coins/base_archive_op_node.json b/configs/coins/base_archive_op_node.json new file mode 100644 index 0000000000..b50e4d3cb1 --- /dev/null +++ b/configs/coins/base_archive_op_node.json @@ -0,0 +1,38 @@ +{ + "coin": { + "name": "Base Archive Op-Node", + "shortcut": "ETH", + "label": "Base", + "alias": "base_archive_op_node" + }, + "ports": { + "backend_rpc": 8212, + "blockbook_internal": 9212, + "blockbook_public": 9312 + }, + "backend": { + "package_name": "backend-base-archive-op-node", + "package_revision": "satoshilabs-1", + "system_user": "base", + "version": "1.9.4", + "docker_image": "us-docker.pkg.dev/oplabs-tools-artifacts/images/op-node:v1.9.4", + "verification_type": "docker", + "verification_source": "105e09e0ec09e375221eda0fa657609f60da5df1b7c52dd4fb4cd61d2f86d5ff", + "extract_command": "docker cp extract:/usr/local/bin/op-node backend/op-node", + "exclude_files": [], + "exec_command_template": "/bin/sh -c '{{.Env.BackendInstallPath}}/{{.Coin.Alias}}/base_archive_op_node_exec.sh 2>&1 >> {{.Env.BackendDataPath}}/{{.Coin.Alias}}/backend/{{.Coin.Alias}}.log'", + "exec_script": "base_archive_op_node.sh", + "logrotate_files_template": "{{.Env.BackendDataPath}}/{{.Coin.Alias}}/backend/{{.Coin.Alias}}.log", + "postinst_script_template": "", + "service_type": "simple", + "service_additional_params_template": "", + "protect_memory": true, + "mainnet": true, + "server_config_file": "", + "client_config_file": "" + }, + "meta": { + "package_maintainer": "IT", + "package_maintainer_email": "it@satoshilabs.com" + } +} \ No newline at end of file diff --git a/configs/coins/base_op_node.json b/configs/coins/base_op_node.json new file mode 100644 index 0000000000..f1da9d5b5c --- /dev/null +++ b/configs/coins/base_op_node.json @@ -0,0 +1,38 @@ +{ + "coin": { + "name": "Base Op-Node", + "shortcut": "ETH", + "label": "Base", + "alias": "base_op_node" + }, + "ports": { + "backend_rpc": 8210, + "blockbook_internal": 9210, + "blockbook_public": 9310 + }, + "backend": { + "package_name": "backend-base-op-node", + "package_revision": "satoshilabs-1", + "system_user": "base", + "version": "1.9.4", + "docker_image": "us-docker.pkg.dev/oplabs-tools-artifacts/images/op-node:v1.9.4", + "verification_type": "docker", + "verification_source": "105e09e0ec09e375221eda0fa657609f60da5df1b7c52dd4fb4cd61d2f86d5ff", + "extract_command": "docker cp extract:/usr/local/bin/op-node backend/op-node", + "exclude_files": [], + "exec_command_template": "/bin/sh -c '{{.Env.BackendInstallPath}}/{{.Coin.Alias}}/base_op_node_exec.sh 2>&1 >> {{.Env.BackendDataPath}}/{{.Coin.Alias}}/backend/{{.Coin.Alias}}.log'", + "exec_script": "base_op_node.sh", + "logrotate_files_template": "{{.Env.BackendDataPath}}/{{.Coin.Alias}}/backend/{{.Coin.Alias}}.log", + "postinst_script_template": "", + "service_type": "simple", + "service_additional_params_template": "", + "protect_memory": true, + "mainnet": true, + "server_config_file": "", + "client_config_file": "" + }, + "meta": { + "package_maintainer": "IT", + "package_maintainer_email": "it@satoshilabs.com" + } +} \ No newline at end of file diff --git a/docs/ports.md b/docs/ports.md index fe51bbb8ef..b99743c669 100644 --- a/docs/ports.md +++ b/docs/ports.md @@ -1,7 +1,7 @@ # Registry of ports | coin | blockbook public | blockbook internal | backend rpc | backend service ports (zmq) | -| -------------------------------- | ---------------- | ------------------ | ----------- | --------------------------------------------------- | +|----------------------------------|------------------|--------------------|-------------|-----------------------------------------------------| | Ethereum Archive | 9116 | 9016 | 8016 | 38316 p2p, 8116 http, 8516 authrpc | | Bitcoin | 9130 | 9030 | 8030 | 38330 | | Bitcoin Cash | 9131 | 9031 | 8031 | 38331 | @@ -59,6 +59,8 @@ | Arbitrum Archive | 9306 | 9206 | 8306 | 38406 p2p | | Arbitrum Nova | 9307 | 9207 | 8207 | 38407 p2p, 8307 http | | Arbitrum Nova Archive | 9308 | 9208 | 8308 | 38408 p2p | +| Base | 9309 | 9209 | 8309 | 38409 p2p, 8209 http, 8409 authrpc | +| Base Archive | 9311 | 9211 | 8211 | 38411 p2p, 8311 http, 8411 authrpc | | Ethereum Testnet Holesky | 19116 | 19016 | 18016 | 18116 http, 18516 authrpc, 48316 p2p | | Bitcoin Signet | 19120 | 19020 | 18020 | 48320 | | Bitcoin Regtest | 19121 | 19021 | 18021 | 48321 | From e4230599a9b894d45c8ed7f15b577218cdfaef85 Mon Sep 17 00:00:00 2001 From: kaladinlight <35275952+kaladinlight@users.noreply.github.com> Date: Mon, 4 Nov 2024 11:47:03 -0700 Subject: [PATCH 03/13] add base archive blockchain factory --- bchain/coins/blockchain.go | 1 + 1 file changed, 1 insertion(+) diff --git a/bchain/coins/blockchain.go b/bchain/coins/blockchain.go index e843174f36..c81620a2c8 100644 --- a/bchain/coins/blockchain.go +++ b/bchain/coins/blockchain.go @@ -149,6 +149,7 @@ func init() { BlockChainFactories["Arbitrum Nova"] = arbitrum.NewArbitrumRPC BlockChainFactories["Arbitrum Nova Archive"] = arbitrum.NewArbitrumRPC BlockChainFactories["Base"] = base.NewBaseRPC + BlockChainFactories["Base Archive"] = base.NewBaseRPC } // NewBlockChain creates bchain.BlockChain and bchain.Mempool for the coin passed by the parameter coin From 6fcc732f83c3f3e074c1c19fbe6502520ec8a35a Mon Sep 17 00:00:00 2001 From: kaladinlight <35275952+kaladinlight@users.noreply.github.com> Date: Wed, 6 Nov 2024 10:51:43 -0700 Subject: [PATCH 04/13] add dbProtoAddrContracts flag and default to legacy encoding. fix tests --- blockbook.go | 11 ++-- db/rocksdb.go | 60 ++++++++++---------- db/rocksdb_ethereumtype.go | 98 +++++++++++++++++++++++++++------ db/rocksdb_ethereumtype_test.go | 86 ++++++++++++++++++++++++++++- db/rocksdb_test.go | 2 +- fiat/fiat_rates_test.go | 2 +- server/public_test.go | 2 +- 7 files changed, 204 insertions(+), 57 deletions(-) diff --git a/blockbook.go b/blockbook.go index 8821dfd502..6bf7d78c35 100644 --- a/blockbook.go +++ b/blockbook.go @@ -43,10 +43,11 @@ const exitCodeFatal = 255 var ( configFile = flag.String("blockchaincfg", "", "path to blockchain RPC service configuration json file") - dbPath = flag.String("datadir", "./data", "path to database directory") - dbCache = flag.Int("dbcache", 1<<29, "size of the rocksdb cache") - dbMaxOpenFiles = flag.Int("dbmaxopenfiles", 1<<14, "max open files by rocksdb") - dbMaxAddrContracts = flag.Int("dbmaxaddrcontracts", 1<<20, "max size of the address contracts map") + dbPath = flag.String("datadir", "./data", "path to database directory") + dbCache = flag.Int("dbcache", 1<<29, "size of the rocksdb cache") + dbMaxOpenFiles = flag.Int("dbmaxopenfiles", 1<<14, "max open files by rocksdb") + dbMaxAddrContracts = flag.Int("dbmaxaddrcontracts", 1<<20, "max size of the address contracts map") + dbProtoAddrContracts = flag.Bool("dbprotoaddrcontracts", false, "use protobuf encoding for addrContracts (also migrates legacy format to protobuf if applicable in existing databases)") blockFrom = flag.Int("blockheight", -1, "height of the starting block") blockUntil = flag.Int("blockuntil", -1, "height of the final block") @@ -170,7 +171,7 @@ func mainWithExitCode() int { return exitCodeFatal } - index, err = db.NewRocksDB(*dbPath, *dbCache, *dbMaxOpenFiles, chain.GetChainParser(), metrics, *extendedIndex, *dbMaxAddrContracts) + index, err = db.NewRocksDB(*dbPath, *dbCache, *dbMaxOpenFiles, chain.GetChainParser(), metrics, *extendedIndex, *dbMaxAddrContracts, *dbProtoAddrContracts) if err != nil { glog.Error("rocksDB: ", err) return exitCodeFatal diff --git a/db/rocksdb.go b/db/rocksdb.go index 5a07ec556b..f28ac1919c 100644 --- a/db/rocksdb.go +++ b/db/rocksdb.go @@ -60,20 +60,21 @@ const ( // RocksDB handle type RocksDB struct { - path string - db *grocksdb.DB - wo *grocksdb.WriteOptions - ro *grocksdb.ReadOptions - cfh []*grocksdb.ColumnFamilyHandle - chainParser bchain.BlockChainParser - is *common.InternalState - metrics *common.Metrics - cache *grocksdb.Cache - maxOpenFiles int - cbs connectBlockStats - extendedIndex bool - maxAddrContracts int - addressContracts map[string]*AddrContracts + path string + db *grocksdb.DB + wo *grocksdb.WriteOptions + ro *grocksdb.ReadOptions + cfh []*grocksdb.ColumnFamilyHandle + chainParser bchain.BlockChainParser + is *common.InternalState + metrics *common.Metrics + cache *grocksdb.Cache + maxOpenFiles int + cbs connectBlockStats + extendedIndex bool + maxAddrContracts int + addressContracts map[string]*AddrContracts + protoAddrContracts bool } const ( @@ -131,7 +132,7 @@ func openDB(path string, c *grocksdb.Cache, openFiles int) (*grocksdb.DB, []*gro // NewRocksDB opens an internal handle to RocksDB environment. Close // needs to be called to release it. -func NewRocksDB(path string, cacheSize, maxOpenFiles int, parser bchain.BlockChainParser, metrics *common.Metrics, extendedIndex bool, maxAddrContracts int) (*RocksDB, error) { +func NewRocksDB(path string, cacheSize, maxOpenFiles int, parser bchain.BlockChainParser, metrics *common.Metrics, extendedIndex bool, maxAddrContracts int, protoAddrContracts bool) (*RocksDB, error) { glog.Infof("rocksdb: opening %s, required data version %v, cache size %v, max open files %v", path, dbVersion, cacheSize, maxOpenFiles) cfNames = append([]string{}, cfBaseNames...) @@ -151,20 +152,21 @@ func NewRocksDB(path string, cacheSize, maxOpenFiles int, parser bchain.BlockCha return nil, err } d := &RocksDB{ - path: path, - db: db, - wo: grocksdb.NewDefaultWriteOptions(), - ro: grocksdb.NewDefaultReadOptions(), - cfh: cfh, - chainParser: parser, - is: nil, - metrics: metrics, - cache: c, - maxOpenFiles: maxOpenFiles, - cbs: connectBlockStats{}, - extendedIndex: extendedIndex, - maxAddrContracts: maxAddrContracts, - addressContracts: make(map[string]*AddrContracts), + path: path, + db: db, + wo: grocksdb.NewDefaultWriteOptions(), + ro: grocksdb.NewDefaultReadOptions(), + cfh: cfh, + chainParser: parser, + is: nil, + metrics: metrics, + cache: c, + maxOpenFiles: maxOpenFiles, + cbs: connectBlockStats{}, + extendedIndex: extendedIndex, + maxAddrContracts: maxAddrContracts, + addressContracts: make(map[string]*AddrContracts), + protoAddrContracts: protoAddrContracts, } return d, nil } diff --git a/db/rocksdb_ethereumtype.go b/db/rocksdb_ethereumtype.go index f16ca6d6e4..bc2e16410d 100644 --- a/db/rocksdb_ethereumtype.go +++ b/db/rocksdb_ethereumtype.go @@ -158,6 +158,44 @@ func packAddrContracts(acs *AddrContracts) ([]byte, error) { return proto.Marshal(pt) } +// packAddrContractsLegacy packs AddrContracts into a legacy manual byte slice +func packAddrContractsLegacy(acs *AddrContracts) []byte { + buf := make([]byte, 0, 128) + varBuf := make([]byte, maxPackedBigintBytes) + l := packVaruint(acs.TotalTxs, varBuf) + buf = append(buf, varBuf[:l]...) + l = packVaruint(acs.NonContractTxs, varBuf) + buf = append(buf, varBuf[:l]...) + l = packVaruint(acs.InternalTxs, varBuf) + buf = append(buf, varBuf[:l]...) + for _, ac := range acs.Contracts { + buf = append(buf, ac.Contract...) + l = packVaruint(uint(ac.Type)+ac.Txs<<2, varBuf) + buf = append(buf, varBuf[:l]...) + if ac.Type == bchain.FungibleToken { + l = packBigint(&ac.Value, varBuf) + buf = append(buf, varBuf[:l]...) + } else if ac.Type == bchain.NonFungibleToken { + l = packVaruint(uint(len(ac.Ids)), varBuf) + buf = append(buf, varBuf[:l]...) + for i := range ac.Ids { + l = packBigint(&ac.Ids[i], varBuf) + buf = append(buf, varBuf[:l]...) + } + } else { // bchain.ERC1155 + l = packVaruint(uint(len(ac.MultiTokenValues)), varBuf) + buf = append(buf, varBuf[:l]...) + for i := range ac.MultiTokenValues { + l = packBigint(&ac.MultiTokenValues[i].Id, varBuf) + buf = append(buf, varBuf[:l]...) + l = packBigint(&ac.MultiTokenValues[i].Value, varBuf) + buf = append(buf, varBuf[:l]...) + } + } + } + return buf +} + // unpackAddrContract unpacks the protobuf encoded byte slice into AddrContracts func unpackAddrContracts(buf []byte, addrDesc bchain.AddressDescriptor) (*AddrContracts, error) { pt := ð.ProtoAddrContracts{} @@ -167,15 +205,19 @@ func unpackAddrContracts(buf []byte, addrDesc bchain.AddressDescriptor) (*AddrCo } contracts := make([]AddrContract, len(pt.Contracts)) for i, c := range pt.Contracts { - ids := make([]big.Int, len(c.Ids)) - for j, id := range c.Ids { - ids[j] = *new(big.Int).SetBytes(id) + var ids []big.Int + if len(c.Ids) > 0 { + ids = make([]big.Int, len(c.Ids)) + for j, id := range c.Ids { + ids[j].SetBytes(id) + } } - multiTokenValues := make(MultiTokenValues, len(c.MultiTokenValues)) - for k, mtv := range c.MultiTokenValues { - multiTokenValues[k] = bchain.MultiTokenValue{ - Id: *new(big.Int).SetBytes(mtv.Id), - Value: *new(big.Int).SetBytes(mtv.Value), + var multiTokenValues MultiTokenValues + if len(c.MultiTokenValues) > 0 { + multiTokenValues = make(MultiTokenValues, len(c.MultiTokenValues)) + for k, mtv := range c.MultiTokenValues { + multiTokenValues[k].Id.SetBytes(mtv.Id) + multiTokenValues[k].Value.SetBytes(mtv.Value) } } contracts[i] = AddrContract{ @@ -261,11 +303,16 @@ func (d *RocksDB) storeAddressContracts(wb *grocksdb.WriteBatch, acm map[string] if acs == nil || (acs.NonContractTxs == 0 && acs.InternalTxs == 0 && len(acs.Contracts) == 0) { wb.DeleteCF(d.cfh[cfAddressContracts], bchain.AddressDescriptor(addrDesc)) } else { - buf, err := packAddrContracts(acs) - if err != nil { - return err + if d.protoAddrContracts { + buf, err := packAddrContracts(acs) + if err != nil { + return err + } + wb.PutCF(d.cfh[cfAddressContracts], bchain.AddressDescriptor(addrDesc), buf) + } else { + buf := packAddrContractsLegacy(acs) + wb.PutCF(d.cfh[cfAddressContracts], bchain.AddressDescriptor(addrDesc), buf) } - wb.PutCF(d.cfh[cfAddressContracts], bchain.AddressDescriptor(addrDesc), buf) } } return nil @@ -282,7 +329,11 @@ func (d *RocksDB) GetAddrDescContracts(addrDesc bchain.AddressDescriptor) (*Addr if len(buf) == 0 { return nil, nil } - return unpackAddrContracts(buf, addrDesc) + if d.protoAddrContracts { + return unpackAddrContracts(buf, addrDesc) + } else { + return unpackAddrContractsLegacy(buf, addrDesc) + } } func findContractInAddressContracts(contract bchain.AddressDescriptor, contracts []AddrContract) (int, bool) { @@ -1458,7 +1509,13 @@ func (d *RocksDB) SortAddressContracts(stop chan os.Signal) error { addrDesc := it.Key().Data() buf := it.Value().Data() if len(buf) > 0 { - ca, err := unpackAddrContracts(buf, addrDesc) + var ca *AddrContracts + var err error + if d.protoAddrContracts { + ca, err = unpackAddrContracts(buf, addrDesc) + } else { + ca, err = unpackAddrContractsLegacy(buf, addrDesc) + } if err != nil { glog.Error("failed to unpack AddrContracts for: ", hex.EncodeToString(addrDesc)) } @@ -1478,11 +1535,16 @@ func (d *RocksDB) SortAddressContracts(stop chan os.Signal) error { if err := func() error { wb := grocksdb.NewWriteBatch() defer wb.Destroy() - buf, err := packAddrContracts(ca) - if err != nil { - return err + if d.protoAddrContracts { + buf, err := packAddrContracts(ca) + if err != nil { + return err + } + wb.PutCF(d.cfh[cfAddressContracts], addrDesc, buf) + } else { + buf := packAddrContractsLegacy(ca) + wb.PutCF(d.cfh[cfAddressContracts], addrDesc, buf) } - wb.PutCF(d.cfh[cfAddressContracts], addrDesc, buf) return d.WriteBatch(wb) }(); err != nil { return errors.Errorf("failed to write cfAddressContracts for: %v: %v", addrDesc, err) diff --git a/db/rocksdb_ethereumtype_test.go b/db/rocksdb_ethereumtype_test.go index c08c5e3eaa..3e516e59d4 100644 --- a/db/rocksdb_ethereumtype_test.go +++ b/db/rocksdb_ethereumtype_test.go @@ -729,6 +729,84 @@ func Test_packUnpackEthInternalData(t *testing.T) { } } +func Test_packUnpackAddrContractsLegacy(t *testing.T) { + parser := ethereumTestnetParser() + type args struct { + buf []byte + addrDesc bchain.AddressDescriptor + } + tests := []struct { + name string + data AddrContracts + }{ + { + name: "1", + data: AddrContracts{ + TotalTxs: 30, + NonContractTxs: 20, + InternalTxs: 10, + Contracts: []AddrContract{}, + }, + }, + { + name: "2", + data: AddrContracts{ + TotalTxs: 12345, + NonContractTxs: 444, + InternalTxs: 8873, + Contracts: []AddrContract{ + { + Type: bchain.FungibleToken, + Contract: addressToAddrDesc(dbtestdata.EthAddrContract0d, parser), + Txs: 8, + Value: *big.NewInt(793201132), + }, + { + Type: bchain.NonFungibleToken, + Contract: addressToAddrDesc(dbtestdata.EthAddrContract47, parser), + Txs: 41235, + Ids: Ids{ + *big.NewInt(1), + *big.NewInt(2), + *big.NewInt(3), + *big.NewInt(3144223412344123), + *big.NewInt(5), + }, + }, + { + Type: bchain.MultiToken, + Contract: addressToAddrDesc(dbtestdata.EthAddrContract4a, parser), + Txs: 64, + MultiTokenValues: MultiTokenValues{ + { + Id: *big.NewInt(1), + Value: *big.NewInt(1412341234), + }, + { + Id: *big.NewInt(123412341234), + Value: *big.NewInt(3), + }, + }, + }, + }, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + packed := packAddrContractsLegacy(&tt.data) + got, err := unpackAddrContractsLegacy(packed, nil) + if err != nil { + t.Errorf("unpackAddrContractsLegacy() error = %v", err) + return + } + if !reflect.DeepEqual(got, &tt.data) { + t.Errorf("unpackAddrContractsLegacy() = %v, want %v", got, &tt.data) + } + }) + } +} + func Test_packUnpackAddrContracts(t *testing.T) { parser := ethereumTestnetParser() type args struct { @@ -794,14 +872,18 @@ func Test_packUnpackAddrContracts(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - packed := packAddrContracts(&tt.data) + packed, err := packAddrContracts(&tt.data) + if err != nil { + t.Errorf("packAddrContracts() error = %v", err) + return + } got, err := unpackAddrContracts(packed, nil) if err != nil { t.Errorf("unpackAddrContracts() error = %v", err) return } if !reflect.DeepEqual(got, &tt.data) { - t.Errorf("unpackAddrContracts() = %v, want %v", got, tt.data) + t.Errorf("unpackAddrContracts() = %+v, want %+v", got, &tt.data) } }) } diff --git a/db/rocksdb_test.go b/db/rocksdb_test.go index 1204b0c3c0..b2d5e5aff7 100644 --- a/db/rocksdb_test.go +++ b/db/rocksdb_test.go @@ -47,7 +47,7 @@ func setupRocksDB(t *testing.T, p bchain.BlockChainParser) *RocksDB { if err != nil { t.Fatal(err) } - d, err := NewRocksDB(tmp, 100000, -1, p, nil, false) + d, err := NewRocksDB(tmp, 100000, -1, p, nil, false, 0, false) if err != nil { t.Fatal(err) } diff --git a/fiat/fiat_rates_test.go b/fiat/fiat_rates_test.go index fad58acfca..b9e02b1113 100644 --- a/fiat/fiat_rates_test.go +++ b/fiat/fiat_rates_test.go @@ -35,7 +35,7 @@ func setupRocksDB(t *testing.T, parser bchain.BlockChainParser, config *common.C if err != nil { t.Fatal(err) } - d, err := db.NewRocksDB(tmp, 100000, -1, parser, nil, false) + d, err := db.NewRocksDB(tmp, 100000, -1, parser, nil, false, 0, false) if err != nil { t.Fatal(err) } diff --git a/server/public_test.go b/server/public_test.go index 550afefe52..a2338d35cd 100644 --- a/server/public_test.go +++ b/server/public_test.go @@ -43,7 +43,7 @@ func setupRocksDB(parser bchain.BlockChainParser, chain bchain.BlockChain, t *te if err != nil { t.Fatal(err) } - d, err := db.NewRocksDB(tmp, 100000, -1, parser, nil, extendedIndex) + d, err := db.NewRocksDB(tmp, 100000, -1, parser, nil, extendedIndex, 0, false) if err != nil { t.Fatal(err) } From 1f2e651f75e4eefc00b0bd3ed146cc2c51b81131 Mon Sep 17 00:00:00 2001 From: kaladinlight <35275952+kaladinlight@users.noreply.github.com> Date: Wed, 6 Nov 2024 11:45:44 -0700 Subject: [PATCH 05/13] default cache behavior for dbMaxAddrContracts default value --- blockbook.go | 2 +- db/bulkconnect.go | 40 ++++++++++++++++++++++---------------- db/rocksdb.go | 2 +- db/rocksdb_ethereumtype.go | 11 +++++++++-- 4 files changed, 34 insertions(+), 21 deletions(-) diff --git a/blockbook.go b/blockbook.go index 6bf7d78c35..ad0aa1efb7 100644 --- a/blockbook.go +++ b/blockbook.go @@ -46,7 +46,7 @@ var ( dbPath = flag.String("datadir", "./data", "path to database directory") dbCache = flag.Int("dbcache", 1<<29, "size of the rocksdb cache") dbMaxOpenFiles = flag.Int("dbmaxopenfiles", 1<<14, "max open files by rocksdb") - dbMaxAddrContracts = flag.Int("dbmaxaddrcontracts", 1<<20, "max size of the address contracts map") + dbMaxAddrContracts = flag.Int("dbmaxaddrcontracts", 0, "max size of the address contracts cache (default bulk mode cache only at static size of 1200000)") dbProtoAddrContracts = flag.Bool("dbprotoaddrcontracts", false, "use protobuf encoding for addrContracts (also migrates legacy format to protobuf if applicable in existing databases)") blockFrom = flag.Int("blockheight", -1, "height of the starting block") diff --git a/db/bulkconnect.go b/db/bulkconnect.go index bac2b75bd0..dba52d86bc 100644 --- a/db/bulkconnect.go +++ b/db/bulkconnect.go @@ -21,15 +21,16 @@ type bulkAddresses struct { // BulkConnect is used to connect blocks in bulk, faster but if interrupted inconsistent way type BulkConnect struct { - d *RocksDB - chainType bchain.ChainType - bulkAddresses []bulkAddresses - bulkAddressesCount int - ethBlockTxs []ethBlockTx - txAddressesMap map[string]*TxAddresses - blockFilters map[string][]byte - balances map[string]*AddrBalance - height uint32 + d *RocksDB + chainType bchain.ChainType + bulkAddresses []bulkAddresses + bulkAddressesCount int + ethBlockTxs []ethBlockTx + txAddressesMap map[string]*TxAddresses + blockFilters map[string][]byte + balances map[string]*AddrBalance + height uint32 + maxBulkAddrContracts int } const ( @@ -43,12 +44,17 @@ const ( // InitBulkConnect initializes bulk connect and switches DB to inconsistent state func (d *RocksDB) InitBulkConnect() (*BulkConnect, error) { + maxBulkAddrContracts := 1200000 + if d.maxAddrContracts != 0 { + maxBulkAddrContracts = d.maxAddrContracts + } b := &BulkConnect{ - d: d, - chainType: d.chainParser.GetChainType(), - txAddressesMap: make(map[string]*TxAddresses), - balances: make(map[string]*AddrBalance), - blockFilters: make(map[string][]byte), + d: d, + chainType: d.chainParser.GetChainType(), + txAddressesMap: make(map[string]*TxAddresses), + balances: make(map[string]*AddrBalance), + blockFilters: make(map[string][]byte), + maxBulkAddrContracts: maxBulkAddrContracts, } if err := d.SetInconsistentState(true); err != nil { return nil, err @@ -270,7 +276,7 @@ func (b *BulkConnect) storeAddressContracts(wb *grocksdb.WriteBatch, all bool) ( for k, a := range b.d.addressContracts { ac[k] = a delete(b.d.addressContracts, k) - if len(ac) >= (b.d.maxAddrContracts / 10) { + if len(ac) >= (b.maxBulkAddrContracts / 10) { break } } @@ -301,14 +307,14 @@ func (b *BulkConnect) parallelStoreAddressContracts(c chan error, all bool) { func (b *BulkConnect) connectBlockEthereumType(block *bchain.Block, storeBlockTxs bool) error { addresses := make(addressesMap) - blockTxs, err := b.d.processAddressesEthereumType(block, addresses, b.d.addressContracts) + blockTxs, err := b.d.processAddressesEthereumType(block, addresses, nil) if err != nil { return err } b.ethBlockTxs = append(b.ethBlockTxs, blockTxs...) var storeAddrContracts chan error var sa bool - if len(b.d.addressContracts) > b.d.maxAddrContracts { + if len(b.d.addressContracts) > b.maxBulkAddrContracts { sa = true storeAddrContracts = make(chan error) go b.parallelStoreAddressContracts(storeAddrContracts, false) diff --git a/db/rocksdb.go b/db/rocksdb.go index f28ac1919c..b82847125c 100644 --- a/db/rocksdb.go +++ b/db/rocksdb.go @@ -410,7 +410,7 @@ func (d *RocksDB) ConnectBlock(block *bchain.Block) error { } } } else if chainType == bchain.ChainEthereumType { - if len(d.addressContracts) > d.maxAddrContracts { + if d.maxAddrContracts > 0 && len(d.addressContracts) > d.maxAddrContracts { d.pruneAddressContracts(1) } addressContracts := make(map[string]*AddrContracts) diff --git a/db/rocksdb_ethereumtype.go b/db/rocksdb_ethereumtype.go index bc2e16410d..a94df657f4 100644 --- a/db/rocksdb_ethereumtype.go +++ b/db/rocksdb_ethereumtype.go @@ -315,6 +315,9 @@ func (d *RocksDB) storeAddressContracts(wb *grocksdb.WriteBatch, acm map[string] } } } + if d.maxAddrContracts == 0 { + d.addressContracts = make(map[string]*AddrContracts) + } return nil } @@ -436,11 +439,15 @@ func (d *RocksDB) addToAddressesAndContractsEthereumType(addrDesc bchain.Address if ac == nil { ac = &AddrContracts{} } - addressContracts[strAddrDesc] = ac + if addressContracts != nil { + addressContracts[strAddrDesc] = ac + } d.addressContracts[strAddrDesc] = ac d.cbs.balancesMiss++ } else { - addressContracts[strAddrDesc] = ac + if addressContracts != nil { + addressContracts[strAddrDesc] = ac + } d.cbs.balancesHit++ } if contract == nil { From 022d17fcb08b21c876e574bfc8d592e2627992ff Mon Sep 17 00:00:00 2001 From: kaladinlight <35275952+kaladinlight@users.noreply.github.com> Date: Wed, 6 Nov 2024 11:57:51 -0700 Subject: [PATCH 06/13] update to defer func to ensure addressContracts is reset and handle possible error --- db/rocksdb_ethereumtype.go | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/db/rocksdb_ethereumtype.go b/db/rocksdb_ethereumtype.go index a94df657f4..b1533411f1 100644 --- a/db/rocksdb_ethereumtype.go +++ b/db/rocksdb_ethereumtype.go @@ -298,6 +298,11 @@ func unpackAddrContractsLegacy(buf []byte, addrDesc bchain.AddressDescriptor) (* } func (d *RocksDB) storeAddressContracts(wb *grocksdb.WriteBatch, acm map[string]*AddrContracts) error { + defer func() { + if d.maxAddrContracts == 0 { + d.addressContracts = make(map[string]*AddrContracts) + } + }() for addrDesc, acs := range acm { // address with 0 contracts is removed from db - happens on disconnect if acs == nil || (acs.NonContractTxs == 0 && acs.InternalTxs == 0 && len(acs.Contracts) == 0) { @@ -315,9 +320,6 @@ func (d *RocksDB) storeAddressContracts(wb *grocksdb.WriteBatch, acm map[string] } } } - if d.maxAddrContracts == 0 { - d.addressContracts = make(map[string]*AddrContracts) - } return nil } @@ -1485,7 +1487,9 @@ func (d *RocksDB) DisconnectBlockRangeEthereumType(lower uint32, higher uint32) wb.DeleteCF(d.cfh[cfHeight], key) wb.DeleteCF(d.cfh[cfBlockInternalDataErrors], key) } - d.storeAddressContracts(wb, contracts) + if err := d.storeAddressContracts(wb, contracts); err != nil { + return err + } err := d.WriteBatch(wb) if err == nil { d.is.RemoveLastBlockTimes(int(higher-lower) + 1) From 9448937d6ef698f592d70d36b4a3abbf44eec972 Mon Sep 17 00:00:00 2001 From: kaladinlight <35275952+kaladinlight@users.noreply.github.com> Date: Wed, 6 Nov 2024 15:45:20 -0700 Subject: [PATCH 07/13] base config default to use dbProtoAddrContracts --- configs/coins/base.json | 2 +- configs/coins/base_archive.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/configs/coins/base.json b/configs/coins/base.json index 1c148b0666..6f7e858d55 100644 --- a/configs/coins/base.json +++ b/configs/coins/base.json @@ -44,7 +44,7 @@ "internal_binding_template": ":{{.Ports.BlockbookInternal}}", "public_binding_template": ":{{.Ports.BlockbookPublic}}", "explorer_url": "", - "additional_params": "", + "additional_params": "-dbprotoaddrcontracts", "block_chain": { "parse": true, "mempool_workers": 8, diff --git a/configs/coins/base_archive.json b/configs/coins/base_archive.json index 735780e0d5..415461bf7a 100644 --- a/configs/coins/base_archive.json +++ b/configs/coins/base_archive.json @@ -44,7 +44,7 @@ "internal_binding_template": ":{{.Ports.BlockbookInternal}}", "public_binding_template": ":{{.Ports.BlockbookPublic}}", "explorer_url": "", - "additional_params": "-workers=16", + "additional_params": "-workers=16 -dbprotoaddrcontracts", "block_chain": { "parse": true, "mempool_workers": 8, From 6efcbfcfa66f31502475dacc9a5a8fec5136d02b Mon Sep 17 00:00:00 2001 From: kaladinlight <35275952+kaladinlight@users.noreply.github.com> Date: Mon, 9 Dec 2024 10:50:20 -0700 Subject: [PATCH 08/13] add network config --- configs/coins/base.json | 1 + configs/coins/base_archive.json | 1 + 2 files changed, 2 insertions(+) diff --git a/configs/coins/base.json b/configs/coins/base.json index 6f7e858d55..d4d7a142e9 100644 --- a/configs/coins/base.json +++ b/configs/coins/base.json @@ -2,6 +2,7 @@ "coin": { "name": "Base", "shortcut": "ETH", + "network": "BASE", "label": "Base", "alias": "base" }, diff --git a/configs/coins/base_archive.json b/configs/coins/base_archive.json index 415461bf7a..7c0c493d6a 100644 --- a/configs/coins/base_archive.json +++ b/configs/coins/base_archive.json @@ -2,6 +2,7 @@ "coin": { "name": "Base Archive", "shortcut": "ETH", + "network": "BASE", "label": "Base", "alias": "base_archive" }, From 540bd1f3bd42ead2a4ce4b1f4575715accce9834 Mon Sep 17 00:00:00 2001 From: kaladinlight <35275952+kaladinlight@users.noreply.github.com> Date: Mon, 9 Dec 2024 11:08:03 -0700 Subject: [PATCH 09/13] update op-geth and op-node versions --- configs/coins/base.json | 6 +++--- configs/coins/base_archive.json | 6 +++--- configs/coins/base_archive_op_node.json | 6 +++--- configs/coins/base_op_node.json | 6 +++--- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/configs/coins/base.json b/configs/coins/base.json index d4d7a142e9..2db5da9586 100644 --- a/configs/coins/base.json +++ b/configs/coins/base.json @@ -22,10 +22,10 @@ "package_name": "backend-base", "package_revision": "satoshilabs-1", "system_user": "base", - "version": "1.101411.0", - "docker_image": "us-docker.pkg.dev/oplabs-tools-artifacts/images/op-geth:v1.101411.0", + "version": "1.101411.3", + "docker_image": "us-docker.pkg.dev/oplabs-tools-artifacts/images/op-geth:v1.101411.3", "verification_type": "docker", - "verification_source": "67f2c6fa24a0d12b0f8b5e251d4f40911baf5229532a06a877749a5a2d9506ff", + "verification_source": "aefecdb139d8e3ed3128e7e3c87abb71198dc6a44ef21f012f391af52679e2c5", "extract_command": "docker cp extract:/usr/local/bin/geth backend/geth", "exclude_files": [], "exec_command_template": "/bin/sh -c '{{.Env.BackendInstallPath}}/{{.Coin.Alias}}/base_exec.sh 2>> {{.Env.BackendDataPath}}/{{.Coin.Alias}}/backend/{{.Coin.Alias}}.log'", diff --git a/configs/coins/base_archive.json b/configs/coins/base_archive.json index 7c0c493d6a..c312adfa41 100644 --- a/configs/coins/base_archive.json +++ b/configs/coins/base_archive.json @@ -22,10 +22,10 @@ "package_name": "backend-base-archive", "package_revision": "satoshilabs-1", "system_user": "base", - "version": "1.101411.0", - "docker_image": "us-docker.pkg.dev/oplabs-tools-artifacts/images/op-geth:v1.101411.0", + "version": "1.101411.3", + "docker_image": "us-docker.pkg.dev/oplabs-tools-artifacts/images/op-geth:v1.101411.3", "verification_type": "docker", - "verification_source": "67f2c6fa24a0d12b0f8b5e251d4f40911baf5229532a06a877749a5a2d9506ff", + "verification_source": "aefecdb139d8e3ed3128e7e3c87abb71198dc6a44ef21f012f391af52679e2c5", "extract_command": "docker cp extract:/usr/local/bin/geth backend/geth", "exclude_files": [], "exec_command_template": "/bin/sh -c '{{.Env.BackendInstallPath}}/{{.Coin.Alias}}/base_archive_exec.sh 2>> {{.Env.BackendDataPath}}/{{.Coin.Alias}}/backend/{{.Coin.Alias}}.log'", diff --git a/configs/coins/base_archive_op_node.json b/configs/coins/base_archive_op_node.json index b50e4d3cb1..85a4c5dbe1 100644 --- a/configs/coins/base_archive_op_node.json +++ b/configs/coins/base_archive_op_node.json @@ -14,10 +14,10 @@ "package_name": "backend-base-archive-op-node", "package_revision": "satoshilabs-1", "system_user": "base", - "version": "1.9.4", - "docker_image": "us-docker.pkg.dev/oplabs-tools-artifacts/images/op-node:v1.9.4", + "version": "1.10.1", + "docker_image": "us-docker.pkg.dev/oplabs-tools-artifacts/images/op-node:v1.10.1", "verification_type": "docker", - "verification_source": "105e09e0ec09e375221eda0fa657609f60da5df1b7c52dd4fb4cd61d2f86d5ff", + "verification_source": "8f40714868fbdc788f67251383a0c0b78a3a937f07b2303bc7d33df5df6297d9", "extract_command": "docker cp extract:/usr/local/bin/op-node backend/op-node", "exclude_files": [], "exec_command_template": "/bin/sh -c '{{.Env.BackendInstallPath}}/{{.Coin.Alias}}/base_archive_op_node_exec.sh 2>&1 >> {{.Env.BackendDataPath}}/{{.Coin.Alias}}/backend/{{.Coin.Alias}}.log'", diff --git a/configs/coins/base_op_node.json b/configs/coins/base_op_node.json index f1da9d5b5c..426d718069 100644 --- a/configs/coins/base_op_node.json +++ b/configs/coins/base_op_node.json @@ -14,10 +14,10 @@ "package_name": "backend-base-op-node", "package_revision": "satoshilabs-1", "system_user": "base", - "version": "1.9.4", - "docker_image": "us-docker.pkg.dev/oplabs-tools-artifacts/images/op-node:v1.9.4", + "version": "1.10.1", + "docker_image": "us-docker.pkg.dev/oplabs-tools-artifacts/images/op-node:v1.10.1", "verification_type": "docker", - "verification_source": "105e09e0ec09e375221eda0fa657609f60da5df1b7c52dd4fb4cd61d2f86d5ff", + "verification_source": "8f40714868fbdc788f67251383a0c0b78a3a937f07b2303bc7d33df5df6297d9", "extract_command": "docker cp extract:/usr/local/bin/op-node backend/op-node", "exclude_files": [], "exec_command_template": "/bin/sh -c '{{.Env.BackendInstallPath}}/{{.Coin.Alias}}/base_op_node_exec.sh 2>&1 >> {{.Env.BackendDataPath}}/{{.Coin.Alias}}/backend/{{.Coin.Alias}}.log'", From b261f837883eacdd648b434f921b60e226b7b976 Mon Sep 17 00:00:00 2001 From: kaladinlight <35275952+kaladinlight@users.noreply.github.com> Date: Mon, 9 Dec 2024 15:44:32 -0700 Subject: [PATCH 10/13] remove coingecko url --- configs/coins/base.json | 2 +- configs/coins/base_archive.json | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/configs/coins/base.json b/configs/coins/base.json index 2db5da9586..75bb4de879 100644 --- a/configs/coins/base.json +++ b/configs/coins/base.json @@ -56,7 +56,7 @@ "queryBackendOnMempoolResync": false, "fiat_rates": "coingecko", "fiat_rates_vs_currencies": "AED,ARS,AUD,BDT,BHD,BMD,BRL,CAD,CHF,CLP,CNY,CZK,DKK,EUR,GBP,HKD,HUF,IDR,ILS,INR,JPY,KRW,KWD,LKR,MMK,MXN,MYR,NGN,NOK,NZD,PHP,PKR,PLN,RUB,SAR,SEK,SGD,THB,TRY,TWD,UAH,USD,VEF,VND,ZAR,BTC,ETH", - "fiat_rates_params": "{\"url\": \"https://api.coingecko.com/api/v3\", \"coin\": \"ethereum\",\"platformIdentifier\": \"ethereum\",\"platformVsCurrency\": \"eth\",\"periodSeconds\": 900}" + "fiat_rates_params": "{\"coin\": \"ethereum\",\"platformIdentifier\": \"ethereum\",\"platformVsCurrency\": \"eth\",\"periodSeconds\": 900}" } } }, diff --git a/configs/coins/base_archive.json b/configs/coins/base_archive.json index c312adfa41..15bc59c721 100644 --- a/configs/coins/base_archive.json +++ b/configs/coins/base_archive.json @@ -58,7 +58,7 @@ "queryBackendOnMempoolResync": false, "fiat_rates": "coingecko", "fiat_rates_vs_currencies": "AED,ARS,AUD,BDT,BHD,BMD,BRL,CAD,CHF,CLP,CNY,CZK,DKK,EUR,GBP,HKD,HUF,IDR,ILS,INR,JPY,KRW,KWD,LKR,MMK,MXN,MYR,NGN,NOK,NZD,PHP,PKR,PLN,RUB,SAR,SEK,SGD,THB,TRY,TWD,UAH,USD,VEF,VND,ZAR,BTC,ETH", - "fiat_rates_params": "{\"url\": \"https://api.coingecko.com/api/v3\", \"coin\": \"ethereum\",\"platformIdentifier\": \"ethereum\",\"platformVsCurrency\": \"eth\",\"periodSeconds\": 900}", + "fiat_rates_params": "{\"coin\": \"ethereum\",\"platformIdentifier\": \"ethereum\",\"platformVsCurrency\": \"eth\",\"periodSeconds\": 900}", "fourByteSignatures": "https://www.4byte.directory/api/v1/signatures/" } } @@ -67,4 +67,4 @@ "package_maintainer": "IT", "package_maintainer_email": "it@satoshilabs.com" } -} +} \ No newline at end of file From d836fb00f3a8a4ef345fd4d342def10eeb749404 Mon Sep 17 00:00:00 2001 From: kaladinlight <35275952+kaladinlight@users.noreply.github.com> Date: Mon, 9 Dec 2024 17:01:20 -0700 Subject: [PATCH 11/13] update coingecko platform identifier --- configs/coins/base.json | 2 +- configs/coins/base_archive.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/configs/coins/base.json b/configs/coins/base.json index 75bb4de879..54d0df983e 100644 --- a/configs/coins/base.json +++ b/configs/coins/base.json @@ -56,7 +56,7 @@ "queryBackendOnMempoolResync": false, "fiat_rates": "coingecko", "fiat_rates_vs_currencies": "AED,ARS,AUD,BDT,BHD,BMD,BRL,CAD,CHF,CLP,CNY,CZK,DKK,EUR,GBP,HKD,HUF,IDR,ILS,INR,JPY,KRW,KWD,LKR,MMK,MXN,MYR,NGN,NOK,NZD,PHP,PKR,PLN,RUB,SAR,SEK,SGD,THB,TRY,TWD,UAH,USD,VEF,VND,ZAR,BTC,ETH", - "fiat_rates_params": "{\"coin\": \"ethereum\",\"platformIdentifier\": \"ethereum\",\"platformVsCurrency\": \"eth\",\"periodSeconds\": 900}" + "fiat_rates_params": "{\"coin\": \"ethereum\",\"platformIdentifier\": \"base\",\"platformVsCurrency\": \"eth\",\"periodSeconds\": 900}" } } }, diff --git a/configs/coins/base_archive.json b/configs/coins/base_archive.json index 15bc59c721..98c0b5df53 100644 --- a/configs/coins/base_archive.json +++ b/configs/coins/base_archive.json @@ -58,7 +58,7 @@ "queryBackendOnMempoolResync": false, "fiat_rates": "coingecko", "fiat_rates_vs_currencies": "AED,ARS,AUD,BDT,BHD,BMD,BRL,CAD,CHF,CLP,CNY,CZK,DKK,EUR,GBP,HKD,HUF,IDR,ILS,INR,JPY,KRW,KWD,LKR,MMK,MXN,MYR,NGN,NOK,NZD,PHP,PKR,PLN,RUB,SAR,SEK,SGD,THB,TRY,TWD,UAH,USD,VEF,VND,ZAR,BTC,ETH", - "fiat_rates_params": "{\"coin\": \"ethereum\",\"platformIdentifier\": \"ethereum\",\"platformVsCurrency\": \"eth\",\"periodSeconds\": 900}", + "fiat_rates_params": "{\"coin\": \"ethereum\",\"platformIdentifier\": \"base\",\"platformVsCurrency\": \"eth\",\"periodSeconds\": 900}", "fourByteSignatures": "https://www.4byte.directory/api/v1/signatures/" } } From e55503c5818985e7ae52ffb1dc9661a628c6bfc8 Mon Sep 17 00:00:00 2001 From: kaladinlight <35275952+kaladinlight@users.noreply.github.com> Date: Mon, 20 Jan 2025 16:36:04 -0700 Subject: [PATCH 12/13] token type -> token standard --- api/types.go | 52 +++++---- api/worker.go | 83 ++++++++------ api/xpub.go | 4 +- bchain/coins/bsc/bscrpc.go | 12 +- bchain/coins/eth/contract.go | 16 +-- bchain/coins/eth/contract_test.go | 10 +- bchain/coins/eth/ethaddrcontracts.pb.go | 44 ++++---- bchain/coins/eth/ethaddrcontracts.proto | 2 +- bchain/coins/eth/ethrpc.go | 2 +- bchain/types.go | 28 ++--- bchain/types_ethereum_type.go | 32 +++--- db/rocksdb_ethereumtype.go | 56 +++++----- db/rocksdb_ethereumtype_test.go | 116 ++++++++++---------- server/internal.go | 2 +- server/public.go | 20 ++-- server/public_ethereumtype_test.go | 8 +- server/public_test.go | 20 ++-- static/templates/address.html | 18 +-- static/templates/tokenDetail.html | 4 +- static/templates/txdetail_ethereumtype.html | 6 +- tests/dbtestdata/dbtestdata_ethereumtype.go | 2 +- tests/dbtestdata/fakechain_ethereumtype.go | 2 +- tests/sync/sync.go | 2 +- 23 files changed, 280 insertions(+), 261 deletions(-) diff --git a/api/types.go b/api/types.go index c283989354..2bb90f101d 100644 --- a/api/types.go +++ b/api/types.go @@ -158,21 +158,23 @@ type MultiTokenValue struct { // Token contains info about tokens held by an address type Token struct { - Type bchain.TokenTypeName `json:"type" ts_type:"'XPUBAddress' | 'ERC20' | 'ERC721' | 'ERC1155'"` - Name string `json:"name"` - Path string `json:"path,omitempty"` - Contract string `json:"contract,omitempty"` - Transfers int `json:"transfers"` - Symbol string `json:"symbol,omitempty"` - Decimals int `json:"decimals,omitempty"` - BalanceSat *Amount `json:"balance,omitempty"` - BaseValue float64 `json:"baseValue,omitempty"` // value in the base currency (ETH for Ethereum) - SecondaryValue float64 `json:"secondaryValue,omitempty"` // value in secondary (fiat) currency, if specified - Ids []Amount `json:"ids,omitempty"` // multiple ERC721 tokens - MultiTokenValues []MultiTokenValue `json:"multiTokenValues,omitempty"` // multiple ERC1155 tokens - TotalReceivedSat *Amount `json:"totalReceived,omitempty"` - TotalSentSat *Amount `json:"totalSent,omitempty"` - ContractIndex string `json:"-"` + // Deprecated: Use Standard instead. + Type bchain.TokenStandardName `json:"type" ts_type:"'XPUBAddress' | 'ERC20' | 'ERC721' | 'ERC1155'"` + Standard bchain.TokenStandardName `json:"standard" ts_type:"'XPUBAddress' | 'ERC20' | 'ERC721' | 'ERC1155'"` + Name string `json:"name"` + Path string `json:"path,omitempty"` + Contract string `json:"contract,omitempty"` + Transfers int `json:"transfers"` + Symbol string `json:"symbol,omitempty"` + Decimals int `json:"decimals,omitempty"` + BalanceSat *Amount `json:"balance,omitempty"` + BaseValue float64 `json:"baseValue,omitempty"` // value in the base currency (ETH for Ethereum) + SecondaryValue float64 `json:"secondaryValue,omitempty"` // value in secondary (fiat) currency, if specified + Ids []Amount `json:"ids,omitempty"` // multiple ERC721 tokens + MultiTokenValues []MultiTokenValue `json:"multiTokenValues,omitempty"` // multiple ERC1155 tokens + TotalReceivedSat *Amount `json:"totalReceived,omitempty"` + TotalSentSat *Amount `json:"totalSent,omitempty"` + ContractIndex string `json:"-"` } // Tokens is array of Token @@ -204,15 +206,17 @@ func (a Tokens) Less(i, j int) bool { // TokenTransfer contains info about a token transfer done in a transaction type TokenTransfer struct { - Type bchain.TokenTypeName `json:"type"` - From string `json:"from"` - To string `json:"to"` - Contract string `json:"contract"` - Name string `json:"name,omitempty"` - Symbol string `json:"symbol,omitempty"` - Decimals int `json:"decimals,omitempty"` - Value *Amount `json:"value,omitempty"` - MultiTokenValues []MultiTokenValue `json:"multiTokenValues,omitempty"` + // Deprecated: Use Standard instead. + Type bchain.TokenStandardName `json:"type"` + Standard bchain.TokenStandardName `json:"standard"` + From string `json:"from"` + To string `json:"to"` + Contract string `json:"contract"` + Name string `json:"name,omitempty"` + Symbol string `json:"symbol,omitempty"` + Decimals int `json:"decimals,omitempty"` + Value *Amount `json:"value,omitempty"` + MultiTokenValues []MultiTokenValue `json:"multiTokenValues,omitempty"` } type EthereumInternalTransfer struct { diff --git a/api/worker.go b/api/worker.go index d478f85c23..9849020832 100644 --- a/api/worker.go +++ b/api/worker.go @@ -176,10 +176,10 @@ func (w *Worker) getAddressAliases(addresses map[string]struct{}) AddressAliases if err != nil || addrDesc == nil { continue } - ci, err := w.db.GetContractInfo(addrDesc, bchain.UnknownTokenType) + ci, err := w.db.GetContractInfo(addrDesc, bchain.UnknownTokenStandard) if err == nil && ci != nil { - if ci.Type == bchain.UnhandledTokenType { - ci, _, err = w.getContractDescriptorInfo(addrDesc, bchain.UnknownTokenType) + if ci.Standard == bchain.UnhandledTokenStandard { + ci, _, err = w.getContractDescriptorInfo(addrDesc, bchain.UnknownTokenStandard) } if err == nil && ci != nil && ci.Name != "" { aliases[a] = AddressAlias{Type: "Contract", Alias: ci.Name} @@ -622,32 +622,32 @@ func (w *Worker) GetTransactionFromMempoolTx(mempoolTx *bchain.MempoolTx) (*Tx, return r, nil } -func (w *Worker) GetContractInfo(contract string, typeFromContext bchain.TokenTypeName) (*bchain.ContractInfo, bool, error) { +func (w *Worker) GetContractInfo(contract string, standardFromContext bchain.TokenStandardName) (*bchain.ContractInfo, bool, error) { cd, err := w.chainParser.GetAddrDescFromAddress(contract) if err != nil { return nil, false, err } - return w.getContractDescriptorInfo(cd, typeFromContext) + return w.getContractDescriptorInfo(cd, standardFromContext) } -func (w *Worker) getContractDescriptorInfo(cd bchain.AddressDescriptor, typeFromContext bchain.TokenTypeName) (*bchain.ContractInfo, bool, error) { +func (w *Worker) getContractDescriptorInfo(cd bchain.AddressDescriptor, standardFromContext bchain.TokenStandardName) (*bchain.ContractInfo, bool, error) { var err error validContract := true - contractInfo, err := w.db.GetContractInfo(cd, typeFromContext) + contractInfo, err := w.db.GetContractInfo(cd, standardFromContext) if err != nil { return nil, false, err } if contractInfo == nil { // log warning only if the contract should have been known from processing of the internal data if eth.ProcessInternalTransactions { - glog.Warningf("Contract %v %v not found in DB", cd, typeFromContext) + glog.Warningf("Contract %v %v not found in DB", cd, standardFromContext) } contractInfo, err = w.chain.GetContractInfo(cd) if err != nil { glog.Errorf("GetContractInfo from chain error %v, contract %v", err, cd) } if contractInfo == nil { - contractInfo = &bchain.ContractInfo{Type: bchain.UnknownTokenType, Decimals: w.chainParser.AmountDecimals()} + contractInfo = &bchain.ContractInfo{Standard: bchain.UnknownTokenStandard, Decimals: w.chainParser.AmountDecimals()} addresses, _, _ := w.chainParser.GetAddressesFromAddrDesc(cd) if len(addresses) > 0 { contractInfo.Contract = addresses[0] @@ -655,14 +655,14 @@ func (w *Worker) getContractDescriptorInfo(cd bchain.AddressDescriptor, typeFrom validContract = false } else { - if typeFromContext != bchain.UnknownTokenType && contractInfo.Type == bchain.UnknownTokenType { - contractInfo.Type = typeFromContext + if standardFromContext != bchain.UnknownTokenStandard && contractInfo.Standard == bchain.UnknownTokenStandard { + contractInfo.Standard = standardFromContext } if err = w.db.StoreContractInfo(contractInfo); err != nil { glog.Errorf("StoreContractInfo error %v, contract %v", err, cd) } } - } else if (contractInfo.Type == bchain.UnhandledTokenType || len(contractInfo.Name) > 0 && contractInfo.Name[0] == 0) || (len(contractInfo.Symbol) > 0 && contractInfo.Symbol[0] == 0) { + } else if (contractInfo.Standard == bchain.UnhandledTokenStandard || len(contractInfo.Name) > 0 && contractInfo.Name[0] == 0) || (len(contractInfo.Symbol) > 0 && contractInfo.Symbol[0] == 0) { // fix contract name/symbol that was parsed as a string consisting of zeroes blockchainContractInfo, err := w.chain.GetContractInfo(cd) if err != nil { @@ -681,9 +681,9 @@ func (w *Worker) getContractDescriptorInfo(cd bchain.AddressDescriptor, typeFrom if blockchainContractInfo != nil { contractInfo.Decimals = blockchainContractInfo.Decimals } - if contractInfo.Type == bchain.UnhandledTokenType { - glog.Infof("Contract %v %v [%s] handled", cd, typeFromContext, contractInfo.Name) - contractInfo.Type = typeFromContext + if contractInfo.Standard == bchain.UnhandledTokenStandard { + glog.Infof("Contract %v %v [%s] handled", cd, standardFromContext, contractInfo.Name) + contractInfo.Standard = standardFromContext } if err = w.db.StoreContractInfo(contractInfo); err != nil { glog.Errorf("StoreContractInfo error %v, contract %v", err, cd) @@ -700,12 +700,12 @@ func (w *Worker) getEthereumTokensTransfers(transfers bchain.TokenTransfers, add contractCache := make(contractInfoCache) for i := range transfers { t := transfers[i] - typeName := bchain.EthereumTokenTypeMap[t.Type] + standardName := bchain.EthereumTokenStandardMap[t.Standard] var contractInfo *bchain.ContractInfo if info, ok := contractCache[t.Contract]; ok { contractInfo = info } else { - info, _, err := w.GetContractInfo(t.Contract, typeName) + info, _, err := w.GetContractInfo(t.Contract, standardName) if err != nil { glog.Errorf("getContractInfo error %v, contract %v", err, t.Contract) continue @@ -715,7 +715,7 @@ func (w *Worker) getEthereumTokensTransfers(transfers bchain.TokenTransfers, add } var value *Amount var values []MultiTokenValue - if t.Type == bchain.MultiToken { + if t.Standard == bchain.MultiToken { values = make([]MultiTokenValue, len(t.MultiTokenValues)) for j := range values { values[j].Id = (*Amount)(&t.MultiTokenValues[j].Id) @@ -727,7 +727,9 @@ func (w *Worker) getEthereumTokensTransfers(transfers bchain.TokenTransfers, add aggregateAddress(addresses, t.From) aggregateAddress(addresses, t.To) tokens[i] = TokenTransfer{ - Type: typeName, + // Deprecated: Use Standard instead. + Type: standardName, + Standard: standardName, Contract: t.Contract, From: t.From, To: t.To, @@ -755,7 +757,7 @@ func (w *Worker) GetEthereumTokenURI(contract string, id string) (string, *bchai if err != nil { return "", nil, err } - ci, _, err := w.getContractDescriptorInfo(cd, bchain.UnknownTokenType) + ci, _, err := w.getContractDescriptorInfo(cd, bchain.UnknownTokenStandard) if err != nil { return "", nil, err } @@ -957,23 +959,25 @@ func computePaging(count, page, itemsOnPage int) (Paging, int, int, int) { } func (w *Worker) getEthereumContractBalance(addrDesc bchain.AddressDescriptor, index int, c *db.AddrContract, details AccountDetails, ticker *common.CurrencyRatesTicker, secondaryCoin string) (*Token, error) { - typeName := bchain.EthereumTokenTypeMap[c.Type] - ci, validContract, err := w.getContractDescriptorInfo(c.Contract, typeName) + standardName := bchain.EthereumTokenStandardMap[c.Standard] + ci, validContract, err := w.getContractDescriptorInfo(c.Contract, standardName) if err != nil { return nil, errors.Annotatef(err, "getEthereumContractBalance %v", c.Contract) } t := Token{ - Contract: ci.Contract, - Name: ci.Name, - Symbol: ci.Symbol, - Type: typeName, + Contract: ci.Contract, + Name: ci.Name, + Symbol: ci.Symbol, + // Deprecated: Use Standard instead. + Type: standardName, + Standard: standardName, Transfers: int(c.Txs), Decimals: ci.Decimals, ContractIndex: strconv.Itoa(index), } // return contract balances/values only at or above AccountDetailsTokenBalances if details >= AccountDetailsTokenBalances && validContract { - if c.Type == bchain.FungibleToken { + if c.Standard == bchain.FungibleToken { // get Erc20 Contract Balance from blockchain, balance obtained from adding and subtracting transfers is not correct b, err := w.chain.EthereumTypeGetErc20ContractBalance(addrDesc, c.Contract) if err != nil { @@ -1022,7 +1026,7 @@ func (w *Worker) getEthereumContractBalance(addrDesc bchain.AddressDescriptor, i // a fallback method in case internal transactions are not processed and there is no indexed info about contract balance for an address func (w *Worker) getEthereumContractBalanceFromBlockchain(addrDesc, contract bchain.AddressDescriptor, details AccountDetails) (*Token, error) { var b *big.Int - ci, validContract, err := w.getContractDescriptorInfo(contract, bchain.UnknownTokenType) + ci, validContract, err := w.getContractDescriptorInfo(contract, bchain.UnknownTokenStandard) if err != nil { return nil, errors.Annotatef(err, "GetContractInfo %v", contract) } @@ -1037,7 +1041,9 @@ func (w *Worker) getEthereumContractBalanceFromBlockchain(addrDesc, contract bch b = nil } return &Token{ - Type: ci.Type, + // Deprecated: Use Standard instead. + Type: ci.Standard, + Standard: ci.Standard, BalanceSat: (*Amount)(b), Contract: ci.Contract, Name: ci.Name, @@ -1142,12 +1148,12 @@ func (w *Worker) getEthereumTypeAddressBalances(addrDesc bchain.AddressDescripto d.tokens = d.tokens[:j] sort.Sort(d.tokens) } - d.contractInfo, err = w.db.GetContractInfo(addrDesc, bchain.UnknownTokenType) + d.contractInfo, err = w.db.GetContractInfo(addrDesc, bchain.UnknownTokenStandard) if err != nil { return nil, nil, err } - if d.contractInfo != nil && d.contractInfo.Type == bchain.UnhandledTokenType { - d.contractInfo, _, err = w.getContractDescriptorInfo(addrDesc, bchain.UnknownTokenType) + if d.contractInfo != nil && d.contractInfo.Standard == bchain.UnhandledTokenStandard { + d.contractInfo, _, err = w.getContractDescriptorInfo(addrDesc, bchain.UnknownTokenStandard) if err != nil { return nil, nil, err } @@ -1467,9 +1473,14 @@ func (w *Worker) GetAddress(address string, page int, txsOnPage int, option Acco AddressAliases: w.getAddressAliases(addresses), StakingPools: ed.stakingPools, } - // keep address backward compatible, set deprecated Erc20Contract value if ERC20 token - if ed.contractInfo != nil && ed.contractInfo.Type == bchain.ERC20TokenType { - r.Erc20Contract = ed.contractInfo + // keep address backward compatible + if ed.contractInfo != nil { + // set deprecated Type value + ed.contractInfo.Type = ed.contractInfo.Standard + // set deprecated Erc20Contract value if ERC20 token + if ed.contractInfo.Standard == bchain.ERC20TokenStandard { + r.Erc20Contract = ed.contractInfo + } } glog.Info("GetAddress-", option, " ", address, ", ", time.Since(start)) return r, nil @@ -1683,7 +1694,7 @@ func (w *Worker) GetBalanceHistory(address string, fromTimestamp, toTimestamp in } // do not get balance history for contracts if w.chainType == bchain.ChainEthereumType { - ci, err := w.db.GetContractInfo(addrDesc, bchain.UnknownTokenType) + ci, err := w.db.GetContractInfo(addrDesc, bchain.UnknownTokenStandard) if err != nil { return nil, err } diff --git a/api/xpub.go b/api/xpub.go index 3a0a6d642f..8f24b9cd33 100644 --- a/api/xpub.go +++ b/api/xpub.go @@ -267,7 +267,9 @@ func (w *Worker) tokenFromXpubAddress(data *xpubData, ad *xpubAddress, changeInd } } return Token{ - Type: bchain.XPUBAddressTokenType, + // Deprecated: Use Standard instead. + Type: bchain.XPUBAddressTokenStandard, + Standard: bchain.XPUBAddressTokenStandard, Name: address, Decimals: w.chainParser.AmountDecimals(), BalanceSat: (*Amount)(balance), diff --git a/bchain/coins/bsc/bscrpc.go b/bchain/coins/bsc/bscrpc.go index a1fb649cd8..96fb648144 100644 --- a/bchain/coins/bsc/bscrpc.go +++ b/bchain/coins/bsc/bscrpc.go @@ -14,10 +14,10 @@ const ( // MainNet is production network MainNet eth.Network = 56 - // bsc token type names - BEP20TokenType bchain.TokenTypeName = "BEP20" - BEP721TokenType bchain.TokenTypeName = "BEP721" - BEP1155TokenType bchain.TokenTypeName = "BEP1155" + // bsc token standard names + BEP20TokenStandard bchain.TokenStandardName = "BEP20" + BEP721TokenStandard bchain.TokenStandardName = "BEP721" + BEP1155TokenStandard bchain.TokenStandardName = "BEP1155" ) // BNBSmartChainRPC is an interface to JSON-RPC bsc service. @@ -32,8 +32,8 @@ func NewBNBSmartChainRPC(config json.RawMessage, pushHandler func(bchain.Notific return nil, err } - // overwrite EthereumTokenTypeMap with bsc specific token type names - bchain.EthereumTokenTypeMap = []bchain.TokenTypeName{BEP20TokenType, BEP721TokenType, BEP1155TokenType} + // overwrite EthereumTokenStandardMap with bsc specific token standard names + bchain.EthereumTokenStandardMap = []bchain.TokenStandardName{BEP20TokenStandard, BEP721TokenStandard, BEP1155TokenStandard} s := &BNBSmartChainRPC{ EthereumRPC: c.(*eth.EthereumRPC), diff --git a/bchain/coins/eth/contract.go b/bchain/coins/eth/contract.go index 6dbca33e3a..899a86e23d 100644 --- a/bchain/coins/eth/contract.go +++ b/bchain/coins/eth/contract.go @@ -51,16 +51,16 @@ func processTransferEvent(l *bchain.RpcLog) (transfer *bchain.TokenTransfer, err } }() tl := len(l.Topics) - var ttt bchain.TokenType + var tts bchain.TokenStandard var value big.Int if tl == 3 { - ttt = bchain.FungibleToken + tts = bchain.FungibleToken _, ok := value.SetString(l.Data, 0) if !ok { return nil, errors.New("ERC20 log Data is not a number") } } else if tl == 4 { - ttt = bchain.NonFungibleToken + tts = bchain.NonFungibleToken _, ok := value.SetString(l.Topics[3], 0) if !ok { return nil, errors.New("ERC721 log Topics[3] is not a number") @@ -78,7 +78,7 @@ func processTransferEvent(l *bchain.RpcLog) (transfer *bchain.TokenTransfer, err return nil, err } return &bchain.TokenTransfer{ - Type: ttt, + Standard: tts, Contract: EIP55AddressFromAddress(l.Address), From: EIP55AddressFromAddress(from), To: EIP55AddressFromAddress(to), @@ -119,7 +119,7 @@ func processERC1155TransferSingleEvent(l *bchain.RpcLog) (transfer *bchain.Token return nil, errors.New("ERC1155 log Data value is not a number") } return &bchain.TokenTransfer{ - Type: bchain.MultiToken, + Standard: bchain.MultiToken, Contract: EIP55AddressFromAddress(l.Address), From: EIP55AddressFromAddress(from), To: EIP55AddressFromAddress(to), @@ -190,7 +190,7 @@ func processERC1155TransferBatchEvent(l *bchain.RpcLog) (transfer *bchain.TokenT idValues[i] = bchain.MultiTokenValue{Id: id, Value: value} } return &bchain.TokenTransfer{ - Type: bchain.MultiToken, + Standard: bchain.MultiToken, Contract: EIP55AddressFromAddress(l.Address), From: EIP55AddressFromAddress(from), To: EIP55AddressFromAddress(to), @@ -239,7 +239,7 @@ func contractGetTransfersFromTx(tx *bchain.RpcTransaction) (bchain.TokenTransfer return nil, errors.New("Data is not a number") } r = append(r, &bchain.TokenTransfer{ - Type: bchain.FungibleToken, + Standard: bchain.FungibleToken, Contract: EIP55AddressFromAddress(tx.To), From: EIP55AddressFromAddress(tx.From), To: EIP55AddressFromAddress(to), @@ -263,7 +263,7 @@ func contractGetTransfersFromTx(tx *bchain.RpcTransaction) (bchain.TokenTransfer return nil, errors.New("Data is not a number") } r = append(r, &bchain.TokenTransfer{ - Type: bchain.NonFungibleToken, + Standard: bchain.NonFungibleToken, Contract: EIP55AddressFromAddress(tx.To), From: EIP55AddressFromAddress(from), To: EIP55AddressFromAddress(to), diff --git a/bchain/coins/eth/contract_test.go b/bchain/coins/eth/contract_test.go index 587d98a774..ca70c85878 100644 --- a/bchain/coins/eth/contract_test.go +++ b/bchain/coins/eth/contract_test.go @@ -133,7 +133,7 @@ func Test_contractGetTransfersFromLog(t *testing.T) { }, want: bchain.TokenTransfers{ { - Type: bchain.NonFungibleToken, + Standard: bchain.NonFungibleToken, Contract: "0x5689b918D34C038901870105A6C7fc24744D31eB", From: "0x0a206d4d5ff79cb5069def7fe3598421cff09391", To: "0x6a016d7eec560549ffa0fbdb7f15c2b27302087f", @@ -171,7 +171,7 @@ func Test_contractGetTransfersFromLog(t *testing.T) { }, want: bchain.TokenTransfers{ { - Type: bchain.MultiToken, + Standard: bchain.MultiToken, Contract: "0x6Fd712E3A5B556654044608F9129040A4839E36c", From: "0xa3950b823cb063dd9afc0d27f35008b805b3ed53", To: "0x4392faf3bb96b5694ecc6ef64726f61cdd4bb0ec", @@ -195,7 +195,7 @@ func Test_contractGetTransfersFromLog(t *testing.T) { }, want: bchain.TokenTransfers{ { - Type: bchain.MultiToken, + Standard: bchain.MultiToken, Contract: "0x6c42c26a081c2f509f8bb68fb7ac3062311ccfb7", From: "0x0000000000000000000000000000000000000000", To: "0x5dc6288b35e0807a3d6feb89b3a2ff4ab773168e", @@ -247,7 +247,7 @@ func Test_contractGetTransfersFromTx(t *testing.T) { args: (b1.Txs[1].CoinSpecificData.(bchain.EthereumSpecificData)).Tx, want: bchain.TokenTransfers{ { - Type: bchain.FungibleToken, + Standard: bchain.FungibleToken, Contract: "0x4af4114f73d1c1c903ac9e0361b379d1291808a2", From: "0x20cd153de35d469ba46127a0c8f18626b59a256a", To: "0x555ee11fbddc0e49a9bab358a8941ad95ffdb48f", @@ -260,7 +260,7 @@ func Test_contractGetTransfersFromTx(t *testing.T) { args: (b2.Txs[2].CoinSpecificData.(bchain.EthereumSpecificData)).Tx, want: bchain.TokenTransfers{ { - Type: bchain.NonFungibleToken, + Standard: bchain.NonFungibleToken, Contract: "0xcda9fc258358ecaa88845f19af595e908bb7efe9", From: "0x837e3f699d85a4b0b99894567e9233dfb1dcb081", To: "0x7b62eb7fe80350dc7ec945c0b73242cb9877fb1b", diff --git a/bchain/coins/eth/ethaddrcontracts.pb.go b/bchain/coins/eth/ethaddrcontracts.pb.go index a57f6687a6..7d24ac84ad 100644 --- a/bchain/coins/eth/ethaddrcontracts.pb.go +++ b/bchain/coins/eth/ethaddrcontracts.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: // protoc-gen-go v1.33.0 -// protoc v4.25.3 +// protoc v5.28.3 // source: bchain/coins/eth/ethaddrcontracts.proto package eth @@ -151,7 +151,7 @@ type ProtoAddrContracts_AddrContract struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Type int64 `protobuf:"varint,1,opt,name=Type,proto3" json:"Type,omitempty"` + Standard int64 `protobuf:"varint,1,opt,name=Standard,proto3" json:"Standard,omitempty"` Contract []byte `protobuf:"bytes,2,opt,name=Contract,proto3" json:"Contract,omitempty"` Txs uint64 `protobuf:"varint,3,opt,name=Txs,proto3" json:"Txs,omitempty"` Value []byte `protobuf:"bytes,4,opt,name=Value,proto3" json:"Value,omitempty"` @@ -191,9 +191,9 @@ func (*ProtoAddrContracts_AddrContract) Descriptor() ([]byte, []int) { return file_bchain_coins_eth_ethaddrcontracts_proto_rawDescGZIP(), []int{0, 1} } -func (x *ProtoAddrContracts_AddrContract) GetType() int64 { +func (x *ProtoAddrContracts_AddrContract) GetStandard() int64 { if x != nil { - return x.Type + return x.Standard } return 0 } @@ -238,7 +238,7 @@ var File_bchain_coins_eth_ethaddrcontracts_proto protoreflect.FileDescriptor var file_bchain_coins_eth_ethaddrcontracts_proto_rawDesc = []byte{ 0x0a, 0x27, 0x62, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x2f, 0x63, 0x6f, 0x69, 0x6e, 0x73, 0x2f, 0x65, 0x74, 0x68, 0x2f, 0x65, 0x74, 0x68, 0x61, 0x64, 0x64, 0x72, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, - 0x63, 0x74, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xbf, 0x03, 0x0a, 0x12, 0x50, 0x72, + 0x63, 0x74, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xc7, 0x03, 0x0a, 0x12, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x41, 0x64, 0x64, 0x72, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x54, 0x6f, 0x74, 0x61, 0x6c, 0x54, 0x78, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x54, 0x6f, 0x74, 0x61, 0x6c, 0x54, 0x78, 0x73, 0x12, 0x26, 0x0a, 0x0e, @@ -254,23 +254,23 @@ var file_bchain_coins_eth_ethaddrcontracts_proto_rawDesc = []byte{ 0x6f, 0x6b, 0x65, 0x6e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x02, 0x49, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x1a, - 0xc9, 0x01, 0x0a, 0x0c, 0x41, 0x64, 0x64, 0x72, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, - 0x12, 0x12, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x04, - 0x54, 0x79, 0x70, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, - 0x12, 0x10, 0x0a, 0x03, 0x54, 0x78, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x03, 0x54, - 0x78, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, - 0x0c, 0x52, 0x05, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x49, 0x64, 0x73, 0x18, - 0x05, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x03, 0x49, 0x64, 0x73, 0x12, 0x4f, 0x0a, 0x10, 0x4d, 0x75, - 0x6c, 0x74, 0x69, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x18, 0x06, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x41, 0x64, 0x64, 0x72, - 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x73, 0x2e, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x54, - 0x6f, 0x6b, 0x65, 0x6e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x10, 0x4d, 0x75, 0x6c, 0x74, 0x69, - 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x42, 0x2e, 0x5a, 0x2c, 0x67, - 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x74, 0x72, 0x65, 0x7a, 0x6f, 0x72, - 0x2f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x62, 0x6f, 0x6f, 0x6b, 0x2f, 0x62, 0x63, 0x68, 0x61, 0x69, - 0x6e, 0x2f, 0x63, 0x6f, 0x69, 0x6e, 0x73, 0x2f, 0x65, 0x74, 0x68, 0x62, 0x06, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x33, + 0xd1, 0x01, 0x0a, 0x0c, 0x41, 0x64, 0x64, 0x72, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, + 0x12, 0x1a, 0x0a, 0x08, 0x53, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x03, 0x52, 0x08, 0x53, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x12, 0x1a, 0x0a, 0x08, + 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, + 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x54, 0x78, 0x73, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x03, 0x54, 0x78, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x56, 0x61, + 0x6c, 0x75, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x56, 0x61, 0x6c, 0x75, 0x65, + 0x12, 0x10, 0x0a, 0x03, 0x49, 0x64, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x03, 0x49, + 0x64, 0x73, 0x12, 0x4f, 0x0a, 0x10, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x54, 0x6f, 0x6b, 0x65, 0x6e, + 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x50, + 0x72, 0x6f, 0x74, 0x6f, 0x41, 0x64, 0x64, 0x72, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, + 0x73, 0x2e, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x56, 0x61, 0x6c, 0x75, + 0x65, 0x52, 0x10, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x56, 0x61, 0x6c, + 0x75, 0x65, 0x73, 0x42, 0x2e, 0x5a, 0x2c, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, + 0x6d, 0x2f, 0x74, 0x72, 0x65, 0x7a, 0x6f, 0x72, 0x2f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x62, 0x6f, + 0x6f, 0x6b, 0x2f, 0x62, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x2f, 0x63, 0x6f, 0x69, 0x6e, 0x73, 0x2f, + 0x65, 0x74, 0x68, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/bchain/coins/eth/ethaddrcontracts.proto b/bchain/coins/eth/ethaddrcontracts.proto index 4402ba6fc7..cd2fecb431 100644 --- a/bchain/coins/eth/ethaddrcontracts.proto +++ b/bchain/coins/eth/ethaddrcontracts.proto @@ -8,7 +8,7 @@ message ProtoAddrContracts { bytes Value = 2; } message AddrContract { - int64 Type = 1; + int64 Standard = 1; bytes Contract = 2; uint64 Txs = 3; bytes Value = 4; diff --git a/bchain/coins/eth/ethrpc.go b/bchain/coins/eth/ethrpc.go index 67b9a28931..4dfffc73b7 100644 --- a/bchain/coins/eth/ethrpc.go +++ b/bchain/coins/eth/ethrpc.go @@ -622,7 +622,7 @@ func (b *EthereumRPC) getCreationContractInfo(contract string, height uint32) *b Contract: contract, } // } - ci.Type = bchain.UnhandledTokenType + ci.Standard = bchain.UnhandledTokenStandard ci.CreatedInBlock = height return ci } diff --git a/bchain/types.go b/bchain/types.go index 8f1c25435f..fa7c4c05f6 100644 --- a/bchain/types.go +++ b/bchain/types.go @@ -116,26 +116,26 @@ type MempoolTx struct { CoinSpecificData interface{} `json:"-"` } -// TokenType - type of token -type TokenType int +// TokenStandard - standard of token +type TokenStandard int -// TokenType enumeration +// TokenStandard enumeration const ( - FungibleToken = TokenType(iota) // ERC20/BEP20 - NonFungibleToken // ERC721/BEP721 - MultiToken // ERC1155/BEP1155 + FungibleToken = TokenStandard(iota) // ERC20/BEP20 + NonFungibleToken // ERC721/BEP721 + MultiToken // ERC1155/BEP1155 ) -// TokenTypeName specifies type of token -type TokenTypeName string +// TokenStandardName specifies standard of token +type TokenStandardName string -// Token types +// Token standards const ( - UnknownTokenType TokenTypeName = "" - UnhandledTokenType TokenTypeName = "-" + UnknownTokenStandard TokenStandardName = "" + UnhandledTokenStandard TokenStandardName = "-" - // XPUBAddressTokenType is address derived from xpub - XPUBAddressTokenType TokenTypeName = "XPUBAddress" + // XPUBAddressTokenStandard is address derived from xpub + XPUBAddressTokenStandard TokenStandardName = "XPUBAddress" ) // TokenTransfers is array of TokenTransfer @@ -144,7 +144,7 @@ type TokenTransfers []*TokenTransfer func (a TokenTransfers) Len() int { return len(a) } func (a TokenTransfers) Swap(i, j int) { a[i], a[j] = a[j], a[i] } func (a TokenTransfers) Less(i, j int) bool { - return a[i].Type < a[j].Type + return a[i].Standard < a[j].Standard } // Block is block header and list of transactions diff --git a/bchain/types_ethereum_type.go b/bchain/types_ethereum_type.go index 652a9edd52..f16bdd070b 100644 --- a/bchain/types_ethereum_type.go +++ b/bchain/types_ethereum_type.go @@ -59,25 +59,27 @@ type EthereumInternalData struct { // ContractInfo contains info about a contract type ContractInfo struct { - Type TokenTypeName `json:"type"` - Contract string `json:"contract"` - Name string `json:"name"` - Symbol string `json:"symbol"` - Decimals int `json:"decimals"` - CreatedInBlock uint32 `json:"createdInBlock,omitempty"` - DestructedInBlock uint32 `json:"destructedInBlock,omitempty"` + // Deprecated: Use Standard instead. + Type TokenStandardName `json:"type"` + Standard TokenStandardName `json:"standard"` + Contract string `json:"contract"` + Name string `json:"name"` + Symbol string `json:"symbol"` + Decimals int `json:"decimals"` + CreatedInBlock uint32 `json:"createdInBlock,omitempty"` + DestructedInBlock uint32 `json:"destructedInBlock,omitempty"` } -// Ethereum token type names +// Ethereum token standard names const ( - ERC20TokenType TokenTypeName = "ERC20" - ERC771TokenType TokenTypeName = "ERC721" - ERC1155TokenType TokenTypeName = "ERC1155" + ERC20TokenStandard TokenStandardName = "ERC20" + ERC771TokenStandard TokenStandardName = "ERC721" + ERC1155TokenStandard TokenStandardName = "ERC1155" ) -// EthereumTokenTypeMap maps bchain.TokenType to TokenTypeName -// the map must match all bchain.TokenType to avoid index out of range panic -var EthereumTokenTypeMap = []TokenTypeName{ERC20TokenType, ERC771TokenType, ERC1155TokenType} +// EthereumTokenStandardMap maps bchain.TokenStandard to TokenStandardName +// the map must match all bchain.TokenStandard to avoid index out of range panic +var EthereumTokenStandardMap = []TokenStandardName{ERC20TokenStandard, ERC771TokenStandard, ERC1155TokenStandard} type MultiTokenValue struct { Id big.Int @@ -86,7 +88,7 @@ type MultiTokenValue struct { // TokenTransfer contains a single token transfer type TokenTransfer struct { - Type TokenType + Standard TokenStandard Contract string From string To string diff --git a/db/rocksdb_ethereumtype.go b/db/rocksdb_ethereumtype.go index b1533411f1..ed687ec188 100644 --- a/db/rocksdb_ethereumtype.go +++ b/db/rocksdb_ethereumtype.go @@ -109,7 +109,7 @@ func (s *MultiTokenValues) upsert(m bchain.MultiTokenValue, index int32, aggrega // AddrContract is Contract address with number of transactions done by given address type AddrContract struct { - Type bchain.TokenType + Standard bchain.TokenStandard Contract bchain.AddressDescriptor Txs uint Value big.Int // single value of ERC20 @@ -144,7 +144,7 @@ func packAddrContracts(acs *AddrContracts) ([]byte, error) { Contract: c.Contract, Ids: ptIds, MultiTokenValues: ptMultiTokenValues, - Type: int64(c.Type), + Standard: int64(c.Standard), Txs: uint64(c.Txs), Value: c.Value.Bytes(), } @@ -170,12 +170,12 @@ func packAddrContractsLegacy(acs *AddrContracts) []byte { buf = append(buf, varBuf[:l]...) for _, ac := range acs.Contracts { buf = append(buf, ac.Contract...) - l = packVaruint(uint(ac.Type)+ac.Txs<<2, varBuf) + l = packVaruint(uint(ac.Standard)+ac.Txs<<2, varBuf) buf = append(buf, varBuf[:l]...) - if ac.Type == bchain.FungibleToken { + if ac.Standard == bchain.FungibleToken { l = packBigint(&ac.Value, varBuf) buf = append(buf, varBuf[:l]...) - } else if ac.Type == bchain.NonFungibleToken { + } else if ac.Standard == bchain.NonFungibleToken { l = packVaruint(uint(len(ac.Ids)), varBuf) buf = append(buf, varBuf[:l]...) for i := range ac.Ids { @@ -221,7 +221,7 @@ func unpackAddrContracts(buf []byte, addrDesc bchain.AddressDescriptor) (*AddrCo } } contracts[i] = AddrContract{ - Type: bchain.TokenType(c.Type), + Standard: bchain.TokenStandard(c.Standard), Contract: c.Contract, Txs: uint(c.Txs), Value: *new(big.Int).SetBytes(c.Value), @@ -254,21 +254,21 @@ func unpackAddrContractsLegacy(buf []byte, addrDesc bchain.AddressDescriptor) (* contract := append(bchain.AddressDescriptor(nil), buf[:eth.EthereumTypeAddressDescriptorLen]...) txs, l := unpackVaruint(buf[eth.EthereumTypeAddressDescriptorLen:]) buf = buf[eth.EthereumTypeAddressDescriptorLen+l:] - ttt := bchain.TokenType(txs & 3) + tts := bchain.TokenStandard(txs & 3) txs >>= 2 ac := AddrContract{ - Type: ttt, + Standard: tts, Contract: contract, Txs: txs, } - if ttt == bchain.FungibleToken { + if tts == bchain.FungibleToken { b, ll := unpackBigint(buf) buf = buf[ll:] ac.Value = b } else { len, ll := unpackVaruint(buf) buf = buf[ll:] - if ttt == bchain.NonFungibleToken { + if tts == bchain.NonFungibleToken { ac.Ids = make(Ids, len) for i := uint(0); i < len; i++ { b, ll := unpackBigint(buf) @@ -410,9 +410,9 @@ func addToContract(c *AddrContract, contractIndex int, index int32, contract bch s.Add(s, v) } } - if transfer.Type == bchain.FungibleToken { + if transfer.Standard == bchain.FungibleToken { aggregate(&c.Value, &transfer.Value) - } else if transfer.Type == bchain.NonFungibleToken { + } else if transfer.Standard == bchain.NonFungibleToken { if index < 0 { c.Ids.remove(transfer.Value) } else { @@ -469,7 +469,7 @@ func (d *RocksDB) addToAddressesAndContractsEthereumType(addrDesc bchain.Address contractIndex = len(ac.Contracts) ac.Contracts = append(ac.Contracts, AddrContract{ Contract: contract, - Type: transfer.Type, + Standard: transfer.Standard, }) } c := &ac.Contracts[contractIndex] @@ -491,7 +491,7 @@ func (d *RocksDB) addToAddressesAndContractsEthereumType(addrDesc bchain.Address type ethBlockTxContract struct { from, to, contract bchain.AddressDescriptor - transferType bchain.TokenType + transferStandard bchain.TokenStandard value big.Int idValues []bchain.MultiTokenValue } @@ -666,7 +666,7 @@ func (d *RocksDB) processContractTransfers(blockTx *ethBlockTx, tx *bchain.Tx, a return err } bc := &blockTx.contracts[i] - bc.transferType = t.Type + bc.transferStandard = t.Standard bc.from = from bc.to = to bc.contract = contract @@ -947,7 +947,7 @@ var cachedContractsMux sync.Mutex func packContractInfo(contractInfo *bchain.ContractInfo) []byte { buf := packString(contractInfo.Name) buf = append(buf, packString(contractInfo.Symbol)...) - buf = append(buf, packString(string(contractInfo.Type))...) + buf = append(buf, packString(string(contractInfo.Standard))...) varBuf := make([]byte, vlq.MaxLen64) l := packVaruint(uint(contractInfo.Decimals), varBuf) buf = append(buf, varBuf[:l]...) @@ -968,7 +968,7 @@ func unpackContractInfo(buf []byte) (*bchain.ContractInfo, error) { contractInfo.Symbol, l = unpackString(buf) buf = buf[l:] s, l = unpackString(buf) - contractInfo.Type = bchain.TokenTypeName(s) + contractInfo.Standard = bchain.TokenStandardName(s) buf = buf[l:] ui, l = unpackVaruint(buf) contractInfo.Decimals = int(ui) @@ -989,9 +989,9 @@ func (d *RocksDB) GetContractInfoForAddress(address string) (*bchain.ContractInf return d.GetContractInfo(contract, "") } -// GetContractInfo gets contract from cache or DB and possibly updates the type from typeFromContext -// it is hard to guess the type of the contract using API, it is easier to set it the first time the contract is processed in a tx -func (d *RocksDB) GetContractInfo(contract bchain.AddressDescriptor, typeFromContext bchain.TokenTypeName) (*bchain.ContractInfo, error) { +// GetContractInfo gets contract from cache or DB and possibly updates the standard from standardFromContext +// it is hard to guess the standard of the contract using API, it is easier to set it the first time the contract is processed in a tx +func (d *RocksDB) GetContractInfo(contract bchain.AddressDescriptor, standardFromContext bchain.TokenStandardName) (*bchain.ContractInfo, error) { cacheKey := string(contract) cachedContractsMux.Lock() contractInfo, found := cachedContracts[cacheKey] @@ -1011,9 +1011,9 @@ func (d *RocksDB) GetContractInfo(contract bchain.AddressDescriptor, typeFromCon if len(addresses) > 0 { contractInfo.Contract = addresses[0] } - // if the type is specified and stored contractInfo has unknown type, set and store it - if typeFromContext != bchain.UnknownTokenType && contractInfo.Type == bchain.UnknownTokenType { - contractInfo.Type = typeFromContext + // if the standard is specified and stored contractInfo has unknown standard, set and store it + if standardFromContext != bchain.UnknownTokenStandard && contractInfo.Standard == bchain.UnknownTokenStandard { + contractInfo.Standard = standardFromContext err = d.db.PutCF(d.wo, d.cfh[cfContracts], contract, packContractInfo(contractInfo)) if err != nil { return nil, err @@ -1078,9 +1078,9 @@ func packBlockTx(buf []byte, blockTx *ethBlockTx) []byte { buf = appendAddress(buf, c.from) buf = appendAddress(buf, c.to) buf = appendAddress(buf, c.contract) - l = packVaruint(uint(c.transferType), varBuf) + l = packVaruint(uint(c.transferStandard), varBuf) buf = append(buf, varBuf[:l]...) - if c.transferType == bchain.MultiToken { + if c.transferStandard == bchain.MultiToken { l = packVaruint(uint(len(c.idValues)), varBuf) buf = append(buf, varBuf[:l]...) for i := range c.idValues { @@ -1242,9 +1242,9 @@ func unpackBlockTx(buf []byte, pos int) (*ethBlockTx, int, error) { return nil, 0, err } cc, l = unpackVaruint(buf[pos:]) - c.transferType = bchain.TokenType(cc) + c.transferStandard = bchain.TokenStandard(cc) pos += l - if c.transferType == bchain.MultiToken { + if c.transferStandard == bchain.MultiToken { cc, l = unpackVaruint(buf[pos:]) pos += l c.idValues = make([]bchain.MultiTokenValue, cc) @@ -1357,7 +1357,7 @@ func (d *RocksDB) disconnectAddress(btxID []byte, internal bool, addrDesc bchain index = transferTo } addToContract(addrContract, contractIndex, index, btxContract.contract, &bchain.TokenTransfer{ - Type: btxContract.transferType, + Standard: btxContract.transferStandard, Value: btxContract.value, MultiTokenValues: btxContract.idValues, }, false) diff --git a/db/rocksdb_ethereumtype_test.go b/db/rocksdb_ethereumtype_test.go index 3e516e59d4..45039a05d5 100644 --- a/db/rocksdb_ethereumtype_test.go +++ b/db/rocksdb_ethereumtype_test.go @@ -756,13 +756,13 @@ func Test_packUnpackAddrContractsLegacy(t *testing.T) { InternalTxs: 8873, Contracts: []AddrContract{ { - Type: bchain.FungibleToken, + Standard: bchain.FungibleToken, Contract: addressToAddrDesc(dbtestdata.EthAddrContract0d, parser), Txs: 8, Value: *big.NewInt(793201132), }, { - Type: bchain.NonFungibleToken, + Standard: bchain.NonFungibleToken, Contract: addressToAddrDesc(dbtestdata.EthAddrContract47, parser), Txs: 41235, Ids: Ids{ @@ -774,7 +774,7 @@ func Test_packUnpackAddrContractsLegacy(t *testing.T) { }, }, { - Type: bchain.MultiToken, + Standard: bchain.MultiToken, Contract: addressToAddrDesc(dbtestdata.EthAddrContract4a, parser), Txs: 64, MultiTokenValues: MultiTokenValues{ @@ -834,13 +834,13 @@ func Test_packUnpackAddrContracts(t *testing.T) { InternalTxs: 8873, Contracts: []AddrContract{ { - Type: bchain.FungibleToken, + Standard: bchain.FungibleToken, Contract: addressToAddrDesc(dbtestdata.EthAddrContract0d, parser), Txs: 8, Value: *big.NewInt(793201132), }, { - Type: bchain.NonFungibleToken, + Standard: bchain.NonFungibleToken, Contract: addressToAddrDesc(dbtestdata.EthAddrContract47, parser), Txs: 41235, Ids: Ids{ @@ -852,7 +852,7 @@ func Test_packUnpackAddrContracts(t *testing.T) { }, }, { - Type: bchain.MultiToken, + Standard: bchain.MultiToken, Contract: addressToAddrDesc(dbtestdata.EthAddrContract4a, parser), Txs: 64, MultiTokenValues: MultiTokenValues{ @@ -912,8 +912,8 @@ func Test_addToContracts(t *testing.T) { index: 1, contract: addressToAddrDesc(dbtestdata.EthAddrContract47, parser), transfer: &bchain.TokenTransfer{ - Type: bchain.FungibleToken, - Value: *big.NewInt(123456), + Standard: bchain.FungibleToken, + Value: *big.NewInt(123456), }, addTxCount: true, }, @@ -921,7 +921,7 @@ func Test_addToContracts(t *testing.T) { wantAddrContracts: &AddrContracts{ Contracts: []AddrContract{ { - Type: bchain.FungibleToken, + Standard: bchain.FungibleToken, Contract: addressToAddrDesc(dbtestdata.EthAddrContract47, parser), Txs: 1, Value: *big.NewInt(123456), @@ -935,8 +935,8 @@ func Test_addToContracts(t *testing.T) { index: ^1, contract: addressToAddrDesc(dbtestdata.EthAddrContract47, parser), transfer: &bchain.TokenTransfer{ - Type: bchain.FungibleToken, - Value: *big.NewInt(23456), + Standard: bchain.FungibleToken, + Value: *big.NewInt(23456), }, addTxCount: true, }, @@ -944,7 +944,7 @@ func Test_addToContracts(t *testing.T) { wantAddrContracts: &AddrContracts{ Contracts: []AddrContract{ { - Type: bchain.FungibleToken, + Standard: bchain.FungibleToken, Contract: addressToAddrDesc(dbtestdata.EthAddrContract47, parser), Value: *big.NewInt(100000), Txs: 2, @@ -958,8 +958,8 @@ func Test_addToContracts(t *testing.T) { index: 1, contract: addressToAddrDesc(dbtestdata.EthAddrContract6f, parser), transfer: &bchain.TokenTransfer{ - Type: bchain.NonFungibleToken, - Value: *big.NewInt(1), + Standard: bchain.NonFungibleToken, + Value: *big.NewInt(1), }, addTxCount: true, }, @@ -967,13 +967,13 @@ func Test_addToContracts(t *testing.T) { wantAddrContracts: &AddrContracts{ Contracts: []AddrContract{ { - Type: bchain.FungibleToken, + Standard: bchain.FungibleToken, Contract: addressToAddrDesc(dbtestdata.EthAddrContract47, parser), Value: *big.NewInt(100000), Txs: 2, }, { - Type: bchain.NonFungibleToken, + Standard: bchain.NonFungibleToken, Contract: addressToAddrDesc(dbtestdata.EthAddrContract6f, parser), Txs: 1, Ids: Ids{*big.NewInt(1)}, @@ -987,8 +987,8 @@ func Test_addToContracts(t *testing.T) { index: 1, contract: addressToAddrDesc(dbtestdata.EthAddrContract6f, parser), transfer: &bchain.TokenTransfer{ - Type: bchain.NonFungibleToken, - Value: *big.NewInt(2), + Standard: bchain.NonFungibleToken, + Value: *big.NewInt(2), }, addTxCount: true, }, @@ -996,13 +996,13 @@ func Test_addToContracts(t *testing.T) { wantAddrContracts: &AddrContracts{ Contracts: []AddrContract{ { - Type: bchain.FungibleToken, + Standard: bchain.FungibleToken, Contract: addressToAddrDesc(dbtestdata.EthAddrContract47, parser), Value: *big.NewInt(100000), Txs: 2, }, { - Type: bchain.NonFungibleToken, + Standard: bchain.NonFungibleToken, Contract: addressToAddrDesc(dbtestdata.EthAddrContract6f, parser), Txs: 2, Ids: Ids{*big.NewInt(1), *big.NewInt(2)}, @@ -1016,8 +1016,8 @@ func Test_addToContracts(t *testing.T) { index: ^1, contract: addressToAddrDesc(dbtestdata.EthAddrContract6f, parser), transfer: &bchain.TokenTransfer{ - Type: bchain.NonFungibleToken, - Value: *big.NewInt(1), + Standard: bchain.NonFungibleToken, + Value: *big.NewInt(1), }, addTxCount: false, }, @@ -1025,13 +1025,13 @@ func Test_addToContracts(t *testing.T) { wantAddrContracts: &AddrContracts{ Contracts: []AddrContract{ { - Type: bchain.FungibleToken, + Standard: bchain.FungibleToken, Contract: addressToAddrDesc(dbtestdata.EthAddrContract47, parser), Value: *big.NewInt(100000), Txs: 2, }, { - Type: bchain.NonFungibleToken, + Standard: bchain.NonFungibleToken, Contract: addressToAddrDesc(dbtestdata.EthAddrContract6f, parser), Txs: 2, Ids: Ids{*big.NewInt(2)}, @@ -1045,7 +1045,7 @@ func Test_addToContracts(t *testing.T) { index: 1, contract: addressToAddrDesc(dbtestdata.EthAddrContractCd, parser), transfer: &bchain.TokenTransfer{ - Type: bchain.MultiToken, + Standard: bchain.MultiToken, MultiTokenValues: []bchain.MultiTokenValue{ { Id: *big.NewInt(11), @@ -1059,19 +1059,19 @@ func Test_addToContracts(t *testing.T) { wantAddrContracts: &AddrContracts{ Contracts: []AddrContract{ { - Type: bchain.FungibleToken, + Standard: bchain.FungibleToken, Contract: addressToAddrDesc(dbtestdata.EthAddrContract47, parser), Value: *big.NewInt(100000), Txs: 2, }, { - Type: bchain.NonFungibleToken, + Standard: bchain.NonFungibleToken, Contract: addressToAddrDesc(dbtestdata.EthAddrContract6f, parser), Txs: 2, Ids: Ids{*big.NewInt(2)}, }, { - Type: bchain.MultiToken, + Standard: bchain.MultiToken, Contract: addressToAddrDesc(dbtestdata.EthAddrContractCd, parser), Txs: 1, MultiTokenValues: MultiTokenValues{ @@ -1090,7 +1090,7 @@ func Test_addToContracts(t *testing.T) { index: 1, contract: addressToAddrDesc(dbtestdata.EthAddrContractCd, parser), transfer: &bchain.TokenTransfer{ - Type: bchain.MultiToken, + Standard: bchain.MultiToken, MultiTokenValues: []bchain.MultiTokenValue{ { Id: *big.NewInt(11), @@ -1108,19 +1108,19 @@ func Test_addToContracts(t *testing.T) { wantAddrContracts: &AddrContracts{ Contracts: []AddrContract{ { - Type: bchain.FungibleToken, + Standard: bchain.FungibleToken, Contract: addressToAddrDesc(dbtestdata.EthAddrContract47, parser), Value: *big.NewInt(100000), Txs: 2, }, { - Type: bchain.NonFungibleToken, + Standard: bchain.NonFungibleToken, Contract: addressToAddrDesc(dbtestdata.EthAddrContract6f, parser), Txs: 2, Ids: Ids{*big.NewInt(2)}, }, { - Type: bchain.MultiToken, + Standard: bchain.MultiToken, Contract: addressToAddrDesc(dbtestdata.EthAddrContractCd, parser), Txs: 2, MultiTokenValues: MultiTokenValues{ @@ -1143,7 +1143,7 @@ func Test_addToContracts(t *testing.T) { index: ^1, contract: addressToAddrDesc(dbtestdata.EthAddrContractCd, parser), transfer: &bchain.TokenTransfer{ - Type: bchain.MultiToken, + Standard: bchain.MultiToken, MultiTokenValues: []bchain.MultiTokenValue{ { Id: *big.NewInt(11), @@ -1161,19 +1161,19 @@ func Test_addToContracts(t *testing.T) { wantAddrContracts: &AddrContracts{ Contracts: []AddrContract{ { - Type: bchain.FungibleToken, + Standard: bchain.FungibleToken, Contract: addressToAddrDesc(dbtestdata.EthAddrContract47, parser), Value: *big.NewInt(100000), Txs: 2, }, { - Type: bchain.NonFungibleToken, + Standard: bchain.NonFungibleToken, Contract: addressToAddrDesc(dbtestdata.EthAddrContract6f, parser), Txs: 2, Ids: Ids{*big.NewInt(2)}, }, { - Type: bchain.MultiToken, + Standard: bchain.MultiToken, Contract: addressToAddrDesc(dbtestdata.EthAddrContractCd, parser), Txs: 3, MultiTokenValues: MultiTokenValues{ @@ -1194,7 +1194,7 @@ func Test_addToContracts(t *testing.T) { contractIndex = len(addrContracts.Contracts) addrContracts.Contracts = append(addrContracts.Contracts, AddrContract{ Contract: tt.args.contract, - Type: tt.args.transfer.Type, + Standard: tt.args.transfer.Standard, }) } if got := addToContract(&addrContracts.Contracts[contractIndex], contractIndex, tt.args.index, tt.args.contract, tt.args.transfer, tt.args.addTxCount); got != tt.wantIndex { @@ -1232,11 +1232,11 @@ func Test_packUnpackBlockTx(t *testing.T) { to: addressToAddrDesc(dbtestdata.EthAddr55, parser), contracts: []ethBlockTxContract{ { - from: addressToAddrDesc(dbtestdata.EthAddr20, parser), - to: addressToAddrDesc(dbtestdata.EthAddr5d, parser), - contract: addressToAddrDesc(dbtestdata.EthAddrContract4a, parser), - transferType: bchain.FungibleToken, - value: *big.NewInt(10000), + from: addressToAddrDesc(dbtestdata.EthAddr20, parser), + to: addressToAddrDesc(dbtestdata.EthAddr5d, parser), + contract: addressToAddrDesc(dbtestdata.EthAddrContract4a, parser), + transferStandard: bchain.FungibleToken, + value: *big.NewInt(10000), }, }, }, @@ -1250,24 +1250,24 @@ func Test_packUnpackBlockTx(t *testing.T) { to: addressToAddrDesc(dbtestdata.EthAddr55, parser), contracts: []ethBlockTxContract{ { - from: addressToAddrDesc(dbtestdata.EthAddr20, parser), - to: addressToAddrDesc(dbtestdata.EthAddr3e, parser), - contract: addressToAddrDesc(dbtestdata.EthAddrContract4a, parser), - transferType: bchain.FungibleToken, - value: *big.NewInt(987654321), + from: addressToAddrDesc(dbtestdata.EthAddr20, parser), + to: addressToAddrDesc(dbtestdata.EthAddr3e, parser), + contract: addressToAddrDesc(dbtestdata.EthAddrContract4a, parser), + transferStandard: bchain.FungibleToken, + value: *big.NewInt(987654321), }, { - from: addressToAddrDesc(dbtestdata.EthAddr4b, parser), - to: addressToAddrDesc(dbtestdata.EthAddr55, parser), - contract: addressToAddrDesc(dbtestdata.EthAddrContract6f, parser), - transferType: bchain.NonFungibleToken, - value: *big.NewInt(13), + from: addressToAddrDesc(dbtestdata.EthAddr4b, parser), + to: addressToAddrDesc(dbtestdata.EthAddr55, parser), + contract: addressToAddrDesc(dbtestdata.EthAddrContract6f, parser), + transferStandard: bchain.NonFungibleToken, + value: *big.NewInt(13), }, { - from: addressToAddrDesc(dbtestdata.EthAddr5d, parser), - to: addressToAddrDesc(dbtestdata.EthAddr7b, parser), - contract: addressToAddrDesc(dbtestdata.EthAddrContractCd, parser), - transferType: bchain.MultiToken, + from: addressToAddrDesc(dbtestdata.EthAddr5d, parser), + to: addressToAddrDesc(dbtestdata.EthAddr7b, parser), + contract: addressToAddrDesc(dbtestdata.EthAddrContractCd, parser), + transferStandard: bchain.MultiToken, idValues: []bchain.MultiTokenValue{ { Id: *big.NewInt(1234), @@ -1351,7 +1351,7 @@ func Test_packUnpackContractInfo(t *testing.T) { { name: "unknown", contractInfo: bchain.ContractInfo{ - Type: bchain.UnknownTokenType, + Standard: bchain.UnknownTokenStandard, Name: "Test contract", Symbol: "TCT", Decimals: 18, @@ -1362,7 +1362,7 @@ func Test_packUnpackContractInfo(t *testing.T) { { name: "ERC20", contractInfo: bchain.ContractInfo{ - Type: bchain.ERC20TokenType, + Standard: bchain.ERC20TokenStandard, Name: "GreenContract🟢", Symbol: "🟢", Decimals: 0, diff --git a/server/internal.go b/server/internal.go index 2544c05bd9..e440fbd8e6 100644 --- a/server/internal.go +++ b/server/internal.go @@ -242,7 +242,7 @@ func (s *InternalServer) apiContractInfo(r *http.Request, apiVersion int) (inter return nil, api.NewAPIError("Missing contract address", true) } - contractInfo, valid, err := s.api.GetContractInfo(contractAddress, bchain.UnknownTokenType) + contractInfo, valid, err := s.api.GetContractInfo(contractAddress, bchain.UnknownTokenStandard) if err != nil { return nil, api.NewAPIError(err.Error(), true) } diff --git a/server/public.go b/server/public.go index e2d8c11903..0c81f41cc9 100644 --- a/server/public.go +++ b/server/public.go @@ -299,9 +299,9 @@ func (s *PublicServer) newTemplateData(r *http.Request) *TemplateData { TOSLink: api.Text.TOSLink, } if t.ChainType == bchain.ChainEthereumType { - t.FungibleTokenName = bchain.EthereumTokenTypeMap[bchain.FungibleToken] - t.NonFungibleTokenName = bchain.EthereumTokenTypeMap[bchain.NonFungibleToken] - t.MultiTokenName = bchain.EthereumTokenTypeMap[bchain.MultiToken] + t.FungibleTokenName = bchain.EthereumTokenStandardMap[bchain.FungibleToken] + t.NonFungibleTokenName = bchain.EthereumTokenStandardMap[bchain.NonFungibleToken] + t.MultiTokenName = bchain.EthereumTokenStandardMap[bchain.MultiToken] } if !s.debug { t.Minified = ".min.4" @@ -378,9 +378,9 @@ type TemplateData struct { CoinLabel string InternalExplorer bool ChainType bchain.ChainType - FungibleTokenName bchain.TokenTypeName - NonFungibleTokenName bchain.TokenTypeName - MultiTokenName bchain.TokenTypeName + FungibleTokenName bchain.TokenStandardName + NonFungibleTokenName bchain.TokenStandardName + MultiTokenName bchain.TokenStandardName Address *api.Address AddrStr string Tx *api.Tx @@ -742,10 +742,10 @@ func isOwnAddress(td *TemplateData, a string) bool { } // called from template, returns count of token transfers of given type in a tx -func tokenTransfersCount(tx *api.Tx, t bchain.TokenTypeName) int { +func tokenTransfersCount(tx *api.Tx, s bchain.TokenStandardName) int { count := 0 for i := range tx.TokenTransfers { - if tx.TokenTransfers[i].Type == t { + if tx.TokenTransfers[i].Standard == s { count++ } } @@ -753,10 +753,10 @@ func tokenTransfersCount(tx *api.Tx, t bchain.TokenTypeName) int { } // called from template, returns count of tokens in array of given type -func tokenCount(tokens []api.Token, t bchain.TokenTypeName) int { +func tokenCount(tokens []api.Token, s bchain.TokenStandardName) int { count := 0 for i := range tokens { - if tokens[i].Type == t { + if tokens[i].Standard == s { count++ } } diff --git a/server/public_ethereumtype_test.go b/server/public_ethereumtype_test.go index a0714f4706..b35d293d4b 100644 --- a/server/public_ethereumtype_test.go +++ b/server/public_ethereumtype_test.go @@ -51,7 +51,7 @@ func httpTestsEthereumType(t *testing.T, ts *httptest.Server) { r: newGetRequest(ts.URL + "/nft/" + dbtestdata.EthAddrContractCd + "/" + "1"), status: http.StatusOK, contentType: "text/html; charset=utf-8", - body: []string{`
Token ID | 1 |
Contract | 0xcdA9FC258358EcaA88845f19Af595e908bb7EfE9 Contract 205 |
Contract type | ERC20 |
Loading metadata from https://ipfs.io/ipfs/cda9fc258358ecaa88845f19af595e908bb7efe9.json...
Token ID | 1 |
Contract | 0xcdA9FC258358EcaA88845f19Af595e908bb7EfE9 Contract 205 |
Contract standard | ERC20 |
Loading metadata from https://ipfs.io/ipfs/cda9fc258358ecaa88845f19af595e908bb7efe9.json...
Token ID | 1 |
Contract | 0xcdA9FC258358EcaA88845f19Af595e908bb7EfE9 Contract 205 |
Contract standard | ERC20 |
Loading metadata from https://ipfs.io/ipfs/cda9fc258358ecaa88845f19af595e908bb7efe9.json...
Token ID | 1 |
Contract | 0xcdA9FC258358EcaA88845f19Af595e908bb7EfE9 Contract 205 |
Standard | ERC20 |
Loading metadata from https://ipfs.io/ipfs/cda9fc258358ecaa88845f19af595e908bb7efe9.json...