From c1dfad0967b7f0fa7f660e62499515972263112a Mon Sep 17 00:00:00 2001 From: Jonathan Downing Date: Mon, 16 Dec 2024 17:10:17 -0600 Subject: [PATCH] Added reorg logic and quai_getLockupsForContractAndMiner API --- core/headerchain.go | 40 ++++ core/rawdb/accessors_chain.go | 71 +++++++ core/rawdb/schema.go | 50 ++++- core/state_processor.go | 69 ++++--- core/types/proto_block.pb.go | 360 ++++++++++++++++++++++------------ core/types/proto_block.proto | 8 + core/types/receipt.go | 4 + core/vm/contracts.go | 34 ++++ core/vm/evm.go | 1 + internal/quaiapi/quai_api.go | 13 ++ 10 files changed, 501 insertions(+), 149 deletions(-) diff --git a/core/headerchain.go b/core/headerchain.go index 6918576bc9..e6e5be1d70 100644 --- a/core/headerchain.go +++ b/core/headerchain.go @@ -528,6 +528,26 @@ func (hc *HeaderChain) SetCurrentHeader(head *types.WorkObject) error { } hc.headerDb.Delete(key) } + createdCoinbaseKeys, err := rawdb.ReadCreatedCoinbaseLockupKeys(hc.headerDb, prevHeader.Hash()) + if err != nil { + return err + } + for _, key := range createdCoinbaseKeys { + if len(key) != rawdb.CoinbaseLockupKeyLength { + return fmt.Errorf("invalid created coinbase key length: %d", len(key)) + } + hc.headerDb.Delete(key) + } + deletedCoinbases, err := rawdb.ReadDeletedCoinbaseLockups(hc.headerDb, prevHeader.Hash()) + if err != nil { + return err + } + for key, coinbase := range deletedCoinbases { + if len(key) != rawdb.CoinbaseLockupKeyLength { + return fmt.Errorf("invalid deleted coinbase key length: %d", len(key)) + } + hc.headerDb.Put(key[:], coinbase) + } } prevHeader = hc.GetHeaderByHash(prevHeader.ParentHash(hc.NodeCtx())) if prevHeader == nil { @@ -592,6 +612,26 @@ func (hc *HeaderChain) SetCurrentHeader(head *types.WorkObject) error { for _, key := range utxoKeys { hc.headerDb.Delete(key) } + createdCoinbaseKeys, err := rawdb.ReadCreatedCoinbaseLockupKeys(hc.headerDb, prevHeader.Hash()) + if err != nil { + return err + } + for _, key := range createdCoinbaseKeys { + if len(key) != rawdb.CoinbaseLockupKeyLength { + return fmt.Errorf("invalid created coinbase key length: %d", len(key)) + } + hc.headerDb.Delete(key) + } + deletedCoinbases, err := rawdb.ReadDeletedCoinbaseLockups(hc.headerDb, prevHeader.Hash()) + if err != nil { + return err + } + for key, coinbase := range deletedCoinbases { + if len(key) != rawdb.CoinbaseLockupKeyLength { + return fmt.Errorf("invalid deleted coinbase key length: %d", len(key)) + } + hc.headerDb.Put(key[:], coinbase) + } } } for k := len(prevHashStack) - 1; k >= 0; k-- { diff --git a/core/rawdb/accessors_chain.go b/core/rawdb/accessors_chain.go index 78f1569472..dae99998ac 100644 --- a/core/rawdb/accessors_chain.go +++ b/core/rawdb/accessors_chain.go @@ -1567,6 +1567,77 @@ func DeleteCreatedUTXOKeys(db ethdb.KeyValueWriter, blockHash common.Hash) { } } +func WriteCreatedCoinbaseLockupKeys(db ethdb.KeyValueWriter, blockHash common.Hash, keys [][]byte) error { + protoKeys := &types.ProtoKeys{Keys: make([][]byte, 0, len(keys))} + protoKeys.Keys = append(protoKeys.Keys, keys...) + + data, err := proto.Marshal(protoKeys) + if err != nil { + db.Logger().WithField("err", err).Fatal("Failed to rlp encode utxo") + } + return db.Put(createdCoinbaseLockupsKey(blockHash), data) +} + +func ReadCreatedCoinbaseLockupKeys(db ethdb.Reader, blockHash common.Hash) ([][]byte, error) { + // Try to look up the data in leveldb. + data, _ := db.Get(createdCoinbaseLockupsKey(blockHash)) + if len(data) == 0 { + return nil, nil + } + protoKeys := new(types.ProtoKeys) + if err := proto.Unmarshal(data, protoKeys); err != nil { + return nil, err + } + return protoKeys.Keys, nil +} + +func DeleteCreatedCoinbaseLockupKeys(db ethdb.KeyValueWriter, blockHash common.Hash) { + if err := db.Delete(createdCoinbaseLockupsKey(blockHash)); err != nil { + db.Logger().WithField("err", err).Fatal("Failed to delete created coinbase lockup keys") + } +} + +func WriteDeletedCoinbaseLockups(db ethdb.KeyValueWriter, blockHash common.Hash, deletedLockups map[[47]byte][]byte) error { + protoKeysAndValues := &types.ProtoKeysAndValues{KeysAndValues: make([]*types.ProtoKeyValue, 0, len(deletedLockups))} + for key, value := range deletedLockups { + protoKeysAndValues.KeysAndValues = append(protoKeysAndValues.KeysAndValues, &types.ProtoKeyValue{ + Key: key[:], + Value: value, + }) + } + data, err := proto.Marshal(protoKeysAndValues) + if err != nil { + db.Logger().WithField("err", err).Fatal("Failed to rlp encode utxo") + } + return db.Put(deletedCoinbaseLockupsKey(blockHash), data) +} + +func ReadDeletedCoinbaseLockups(db ethdb.Reader, blockHash common.Hash) (map[[47]byte][]byte, error) { + // Try to look up the data in leveldb. + data, _ := db.Get(deletedCoinbaseLockupsKey(blockHash)) + if len(data) == 0 { + return nil, nil + } + protoKeysAndValues := new(types.ProtoKeysAndValues) + if err := proto.Unmarshal(data, protoKeysAndValues); err != nil { + return nil, err + } + deletedLockups := make(map[[47]byte][]byte) + for _, keyValue := range protoKeysAndValues.KeysAndValues { + if len(keyValue.Key) != 47 { + return nil, fmt.Errorf("invalid key length %d", len(keyValue.Key)) + } + deletedLockups[[47]byte(keyValue.Key)] = keyValue.Value + } + return deletedLockups, nil +} + +func DeleteDeletedCoinbaseLockups(db ethdb.KeyValueWriter, blockHash common.Hash) { + if err := db.Delete(deletedCoinbaseLockupsKey(blockHash)); err != nil { + db.Logger().WithField("err", err).Fatal("Failed to delete deleted coinbase lockups") + } +} + func ReadUTXOSetSize(db ethdb.Reader, blockHash common.Hash) uint64 { data, _ := db.Get(utxoSetSizeKey(blockHash)) if len(data) == 0 { diff --git a/core/rawdb/schema.go b/core/rawdb/schema.go index fad383c705..907b1763f5 100644 --- a/core/rawdb/schema.go +++ b/core/rawdb/schema.go @@ -113,8 +113,10 @@ var ( configPrefix = []byte("quai-config-") // config prefix for the db // Chain index prefixes (use `i` + single byte to avoid mixing data types). - BloomBitsIndexPrefix = []byte("iB") // BloomBitsIndexPrefix is the data table of a chain indexer to track its progress - CoinbaseLockupPrefix = []byte("cl") // coinbaseLockupPrefix + ownerContract + beneficiaryMiner + lockupByte + epoch -> lockup + BloomBitsIndexPrefix = []byte("iB") // BloomBitsIndexPrefix is the data table of a chain indexer to track its progress + CoinbaseLockupPrefix = []byte("cl") // coinbaseLockupPrefix + ownerContract + beneficiaryMiner + lockupByte + epoch -> lockup + createdCoinbaseLockupsPrefix = []byte("ccl") // createdCoinbaseLockupsPrefix + hash -> [][]byte + deletedCoinbaseLockupsPrefix = []byte("dcl") // deletedCoinbaseLockupsPrefix + hash -> [][]byte ) const ( @@ -389,6 +391,8 @@ func utxoToBlockHeightKey(txHash common.Hash, index uint16) []byte { return append(utxoToBlockHeightPrefix, txHash[:]...) } +var CoinbaseLockupKeyLength = len(CoinbaseLockupPrefix) + 2*common.AddressLength + 1 + 4 + func CoinbaseLockupKey(ownerContract common.Address, beneficiaryMiner common.Address, lockupByte byte, epoch uint32) []byte { epochBytes := make([]byte, 4) binary.BigEndian.PutUint32(epochBytes, epoch) @@ -399,3 +403,45 @@ func CoinbaseLockupKey(ownerContract common.Address, beneficiaryMiner common.Add combined = append(combined, epochBytes...) return append(CoinbaseLockupPrefix, combined...) } + +func createdCoinbaseLockupsKey(hash common.Hash) []byte { + return append(createdCoinbaseLockupsPrefix, hash.Bytes()...) +} + +func deletedCoinbaseLockupsKey(hash common.Hash) []byte { + return append(deletedCoinbaseLockupsPrefix, hash.Bytes()...) +} + +func ReverseCoinbaseLockupKey(data []byte, location common.Location) (common.Address, common.Address, byte, uint32, error) { + + epochLength := 4 // Length of the epoch in bytes + prefixLength := len(CoinbaseLockupPrefix) + + // Ensure the data is long enough to contain all components + if len(data) < prefixLength+2*common.AddressLength+1+epochLength { + return common.Address{}, common.Address{}, 0, 0, fmt.Errorf("key is too short to parse") + } + + // Check and remove the prefix + if !bytes.HasPrefix(data, CoinbaseLockupPrefix) { + return common.Address{}, common.Address{}, 0, 0, fmt.Errorf("key does not have the correct prefix") + } + data = data[prefixLength:] // Remove the prefix + + // Extract the owner contract address + ownerContract := common.BytesToAddress(data[:common.AddressLength], location) + data = data[common.AddressLength:] // Advance the slice + + // Extract the beneficiary miner address + beneficiaryMiner := common.BytesToAddress(data[:common.AddressLength], location) + data = data[common.AddressLength:] // Advance the slice + + // Extract the lockup byte + lockupByte := data[0] + data = data[1:] // Advance the slice + + // Extract the epoch + epoch := binary.BigEndian.Uint32(data[:epochLength]) + + return ownerContract, beneficiaryMiner, lockupByte, epoch, nil +} diff --git a/core/state_processor.go b/core/state_processor.go index 317b28d4ee..18b511e17a 100644 --- a/core/state_processor.go +++ b/core/state_processor.go @@ -206,13 +206,14 @@ func NewStateProcessor(config *params.ChainConfig, hc *HeaderChain, engine conse } type UtxosCreatedDeleted struct { - UtxosCreatedKeys [][]byte - UtxosCreatedHashes []common.Hash - UtxosDeleted []*types.SpentUtxoEntry - UtxosDeletedHashes []common.Hash - CoinbaseLockupsCreated map[string]common.Hash - CoinbaseLockupsDeleted map[string]common.Hash - RotatedEpochs map[string]struct{} + UtxosCreatedKeys [][]byte + UtxosCreatedHashes []common.Hash + UtxosDeleted []*types.SpentUtxoEntry + UtxosDeletedHashes []common.Hash + CoinbaseLockupsCreatedHashes map[string]common.Hash + CoinbaseLockupsDeletedHashes map[string]common.Hash + CoinbaseLockupsDeleted map[[47]byte][]byte + RotatedEpochs map[string]struct{} } // Process processes the state changes according to the Quai rules by running @@ -263,8 +264,9 @@ func (p *StateProcessor) Process(block *types.WorkObject, batch ethdb.Batch) (ty return types.Receipts{}, []*types.Transaction{}, []*types.Log{}, nil, 0, 0, 0, nil, nil, err } utxosCreatedDeleted := new(UtxosCreatedDeleted) // utxos created and deleted in this block - utxosCreatedDeleted.CoinbaseLockupsCreated = make(map[string]common.Hash) - utxosCreatedDeleted.CoinbaseLockupsDeleted = make(map[string]common.Hash) + utxosCreatedDeleted.CoinbaseLockupsCreatedHashes = make(map[string]common.Hash) + utxosCreatedDeleted.CoinbaseLockupsDeletedHashes = make(map[string]common.Hash) + utxosCreatedDeleted.CoinbaseLockupsDeleted = make(map[[47]byte][]byte) utxosCreatedDeleted.RotatedEpochs = make(map[string]struct{}) // Apply the previous inbound ETXs to the ETX set state prevInboundEtxs := rawdb.ReadInboundEtxs(p.hc.bc.db, header.ParentHash(nodeCtx)) @@ -591,14 +593,14 @@ func (p *StateProcessor) Process(block *types.WorkObject, batch ethdb.Batch) (ty return nil, nil, nil, nil, 0, 0, 0, nil, nil, fmt.Errorf("could not add new lock: %w", err) } // Store the new lockup key every time - utxosCreatedDeleted.CoinbaseLockupsCreated[string(newCoinbaseLockupKey)] = *newCoinbaseLockupHash + utxosCreatedDeleted.CoinbaseLockupsCreatedHashes[string(newCoinbaseLockupKey)] = *newCoinbaseLockupHash if oldCoinbaseLockupHash != nil { // We deleted (updated) the old lockup, write it to deleted list but only the first time - if _, exists := utxosCreatedDeleted.CoinbaseLockupsDeleted[string(oldCoinbaseLockupKey)]; !exists { + if _, exists := utxosCreatedDeleted.CoinbaseLockupsDeletedHashes[string(oldCoinbaseLockupKey)]; !exists { if _, exists := utxosCreatedDeleted.RotatedEpochs[string(newCoinbaseLockupKey)]; !exists { // We only want to add a delete if we have not rotated the epoch (we haven't created a new lock) because otherwise there is nothing to delete - utxosCreatedDeleted.CoinbaseLockupsDeleted[string(oldCoinbaseLockupKey)] = *oldCoinbaseLockupHash + utxosCreatedDeleted.CoinbaseLockupsDeletedHashes[string(oldCoinbaseLockupKey)] = *oldCoinbaseLockupHash utxosCreatedDeleted.UtxosDeletedHashes = append(utxosCreatedDeleted.UtxosDeletedHashes, *oldCoinbaseLockupHash) } } @@ -659,14 +661,13 @@ func (p *StateProcessor) Process(block *types.WorkObject, batch ethdb.Batch) (ty return nil, nil, nil, nil, 0, 0, 0, nil, nil, fmt.Errorf("could not add new lock: %w", err) } // Store the new lockup key every time - utxosCreatedDeleted.CoinbaseLockupsCreated[string(newCoinbaseLockupKey)] = *newCoinbaseLockupHash + utxosCreatedDeleted.CoinbaseLockupsCreatedHashes[string(newCoinbaseLockupKey)] = *newCoinbaseLockupHash if oldCoinbaseLockupHash != nil { // We deleted (updated) the old lockup, write it to deleted list but only the first time - if _, exists := utxosCreatedDeleted.CoinbaseLockupsDeleted[string(oldCoinbaseLockupKey)]; !exists { - if _, exists := utxosCreatedDeleted.RotatedEpochs[string(newCoinbaseLockupKey)]; !exists { - // Don't register deletes for any rotated epochs - utxosCreatedDeleted.CoinbaseLockupsDeleted[string(oldCoinbaseLockupKey)] = *oldCoinbaseLockupHash + if _, exists := utxosCreatedDeleted.CoinbaseLockupsDeletedHashes[string(oldCoinbaseLockupKey)]; !exists { + if _, exists := utxosCreatedDeleted.RotatedEpochs[string(newCoinbaseLockupKey)]; !exists { // Don't register deletes for any rotated epochs + utxosCreatedDeleted.CoinbaseLockupsDeletedHashes[string(oldCoinbaseLockupKey)] = *oldCoinbaseLockupHash utxosCreatedDeleted.UtxosDeletedHashes = append(utxosCreatedDeleted.UtxosDeletedHashes, *oldCoinbaseLockupHash) } } @@ -802,10 +803,16 @@ func (p *StateProcessor) Process(block *types.WorkObject, batch ethdb.Batch) (ty totalEtxGas += receipt.GasUsed timeDelta := time.Since(startTimeEtx) timeQiToQuai += timeDelta - for _, etx := range receipt.OutboundEtxs { - if receipt.Status == types.ReceiptStatusSuccessful { + if receipt.Status == types.ReceiptStatusSuccessful { + for _, etx := range receipt.OutboundEtxs { emittedEtxs = append(emittedEtxs, etx) } + for _, hash := range receipt.CoinbaseLockupDeletedHashes { + utxosCreatedDeleted.UtxosDeletedHashes = append(utxosCreatedDeleted.UtxosDeletedHashes, *hash) + } + for key, lockup := range receipt.CoinbaseLockupsDeleted { + utxosCreatedDeleted.CoinbaseLockupsDeleted[key] = lockup + } } receipts = append(receipts, receipt) allLogs = append(allLogs, receipt.Logs...) @@ -845,10 +852,16 @@ func (p *StateProcessor) Process(block *types.WorkObject, batch ethdb.Batch) (ty minGasPrice = new(big.Int).Set(gasPrice) } } - for _, etx := range receipt.OutboundEtxs { - if receipt.Status == types.ReceiptStatusSuccessful { + if receipt.Status == types.ReceiptStatusSuccessful { + for _, etx := range receipt.OutboundEtxs { emittedEtxs = append(emittedEtxs, etx) } + for _, hash := range receipt.CoinbaseLockupDeletedHashes { + utxosCreatedDeleted.UtxosDeletedHashes = append(utxosCreatedDeleted.UtxosDeletedHashes, *hash) + } + for key, lockup := range receipt.CoinbaseLockupsDeleted { + utxosCreatedDeleted.CoinbaseLockupsDeleted[key] = lockup + } } receipts = append(receipts, receipt) allLogs = append(allLogs, receipt.Logs...) @@ -979,7 +992,7 @@ func (p *StateProcessor) Process(block *types.WorkObject, batch ethdb.Batch) (ty } } - for _, hash := range utxosCreatedDeleted.CoinbaseLockupsCreated { + for _, hash := range utxosCreatedDeleted.CoinbaseLockupsCreatedHashes { // Update the created hash list with the latest new elements (instead of intermediate ones) utxosCreatedDeleted.UtxosCreatedHashes = append(utxosCreatedDeleted.UtxosCreatedHashes, hash) } @@ -1034,6 +1047,16 @@ func (p *StateProcessor) Process(block *types.WorkObject, batch ethdb.Batch) (ty if err := rawdb.WriteCreatedUTXOKeys(batch, blockHash, utxosCreatedDeleted.UtxosCreatedKeys); err != nil { // Could do this in Apply instead return nil, nil, nil, nil, 0, 0, 0, nil, nil, err } + coinbaseLockupsCreatedKeys := make([][]byte, 0, len(utxosCreatedDeleted.CoinbaseLockupsCreatedHashes)) + for key, _ := range utxosCreatedDeleted.CoinbaseLockupsCreatedHashes { + coinbaseLockupsCreatedKeys = append(coinbaseLockupsCreatedKeys, []byte(key)) + } + if err := rawdb.WriteCreatedCoinbaseLockupKeys(batch, blockHash, coinbaseLockupsCreatedKeys); err != nil { + return nil, nil, nil, nil, 0, 0, 0, nil, nil, err + } + if err := rawdb.WriteDeletedCoinbaseLockups(batch, blockHash, utxosCreatedDeleted.CoinbaseLockupsDeleted); err != nil { + return nil, nil, nil, nil, 0, 0, 0, nil, nil, err + } return receipts, emittedEtxs, allLogs, statedb, *usedGas, *usedState, utxoSetSize, multiSet, unlocks, nil } @@ -1230,6 +1253,8 @@ func applyTransaction(msg types.Message, parent *types.WorkObject, config *param receipt.ContractAddress = *result.ContractAddr } receipt.OutboundEtxs = result.Etxs + receipt.CoinbaseLockupDeletedHashes = evm.CoinbaseDeletedHashes + receipt.CoinbaseLockupsDeleted = evm.CoinbasesDeleted } receipt.TxHash = tx.Hash() receipt.GasUsed = result.UsedGas diff --git a/core/types/proto_block.pb.go b/core/types/proto_block.pb.go index 2f0e902a55..0a8cfc0566 100644 --- a/core/types/proto_block.pb.go +++ b/core/types/proto_block.pb.go @@ -2372,6 +2372,104 @@ func (x *ProtoKeys) GetKeys() [][]byte { return nil } +type ProtoKeyValue struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Key []byte `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"` + Value []byte `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"` +} + +func (x *ProtoKeyValue) Reset() { + *x = ProtoKeyValue{} + mi := &file_core_types_proto_block_proto_msgTypes[35] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ProtoKeyValue) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ProtoKeyValue) ProtoMessage() {} + +func (x *ProtoKeyValue) ProtoReflect() protoreflect.Message { + mi := &file_core_types_proto_block_proto_msgTypes[35] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ProtoKeyValue.ProtoReflect.Descriptor instead. +func (*ProtoKeyValue) Descriptor() ([]byte, []int) { + return file_core_types_proto_block_proto_rawDescGZIP(), []int{35} +} + +func (x *ProtoKeyValue) GetKey() []byte { + if x != nil { + return x.Key + } + return nil +} + +func (x *ProtoKeyValue) GetValue() []byte { + if x != nil { + return x.Value + } + return nil +} + +type ProtoKeysAndValues struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + KeysAndValues []*ProtoKeyValue `protobuf:"bytes,1,rep,name=keys_and_values,json=keysAndValues,proto3" json:"keys_and_values,omitempty"` +} + +func (x *ProtoKeysAndValues) Reset() { + *x = ProtoKeysAndValues{} + mi := &file_core_types_proto_block_proto_msgTypes[36] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ProtoKeysAndValues) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ProtoKeysAndValues) ProtoMessage() {} + +func (x *ProtoKeysAndValues) ProtoReflect() protoreflect.Message { + mi := &file_core_types_proto_block_proto_msgTypes[36] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ProtoKeysAndValues.ProtoReflect.Descriptor instead. +func (*ProtoKeysAndValues) Descriptor() ([]byte, []int) { + return file_core_types_proto_block_proto_rawDescGZIP(), []int{36} +} + +func (x *ProtoKeysAndValues) GetKeysAndValues() []*ProtoKeyValue { + if x != nil { + return x.KeysAndValues + } + return nil +} + type ProtoTrimDepths struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -2382,7 +2480,7 @@ type ProtoTrimDepths struct { func (x *ProtoTrimDepths) Reset() { *x = ProtoTrimDepths{} - mi := &file_core_types_proto_block_proto_msgTypes[35] + mi := &file_core_types_proto_block_proto_msgTypes[37] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2394,7 +2492,7 @@ func (x *ProtoTrimDepths) String() string { func (*ProtoTrimDepths) ProtoMessage() {} func (x *ProtoTrimDepths) ProtoReflect() protoreflect.Message { - mi := &file_core_types_proto_block_proto_msgTypes[35] + mi := &file_core_types_proto_block_proto_msgTypes[37] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2407,7 +2505,7 @@ func (x *ProtoTrimDepths) ProtoReflect() protoreflect.Message { // Deprecated: Use ProtoTrimDepths.ProtoReflect.Descriptor instead. func (*ProtoTrimDepths) Descriptor() ([]byte, []int) { - return file_core_types_proto_block_proto_rawDescGZIP(), []int{35} + return file_core_types_proto_block_proto_rawDescGZIP(), []int{37} } func (x *ProtoTrimDepths) GetTrimDepths() map[uint32]uint64 { @@ -2427,7 +2525,7 @@ type ProtoTokenChoiceSet struct { func (x *ProtoTokenChoiceSet) Reset() { *x = ProtoTokenChoiceSet{} - mi := &file_core_types_proto_block_proto_msgTypes[36] + mi := &file_core_types_proto_block_proto_msgTypes[38] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2439,7 +2537,7 @@ func (x *ProtoTokenChoiceSet) String() string { func (*ProtoTokenChoiceSet) ProtoMessage() {} func (x *ProtoTokenChoiceSet) ProtoReflect() protoreflect.Message { - mi := &file_core_types_proto_block_proto_msgTypes[36] + mi := &file_core_types_proto_block_proto_msgTypes[38] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2452,7 +2550,7 @@ func (x *ProtoTokenChoiceSet) ProtoReflect() protoreflect.Message { // Deprecated: Use ProtoTokenChoiceSet.ProtoReflect.Descriptor instead. func (*ProtoTokenChoiceSet) Descriptor() ([]byte, []int) { - return file_core_types_proto_block_proto_rawDescGZIP(), []int{36} + return file_core_types_proto_block_proto_rawDescGZIP(), []int{38} } func (x *ProtoTokenChoiceSet) GetTokenChoiceArray() []*ProtoTokenChoiceArray { @@ -2472,7 +2570,7 @@ type ProtoTokenChoiceArray struct { func (x *ProtoTokenChoiceArray) Reset() { *x = ProtoTokenChoiceArray{} - mi := &file_core_types_proto_block_proto_msgTypes[37] + mi := &file_core_types_proto_block_proto_msgTypes[39] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2484,7 +2582,7 @@ func (x *ProtoTokenChoiceArray) String() string { func (*ProtoTokenChoiceArray) ProtoMessage() {} func (x *ProtoTokenChoiceArray) ProtoReflect() protoreflect.Message { - mi := &file_core_types_proto_block_proto_msgTypes[37] + mi := &file_core_types_proto_block_proto_msgTypes[39] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2497,7 +2595,7 @@ func (x *ProtoTokenChoiceArray) ProtoReflect() protoreflect.Message { // Deprecated: Use ProtoTokenChoiceArray.ProtoReflect.Descriptor instead. func (*ProtoTokenChoiceArray) Descriptor() ([]byte, []int) { - return file_core_types_proto_block_proto_rawDescGZIP(), []int{37} + return file_core_types_proto_block_proto_rawDescGZIP(), []int{39} } func (x *ProtoTokenChoiceArray) GetTokenChoices() *ProtoTokenChoice { @@ -2519,7 +2617,7 @@ type ProtoTokenChoice struct { func (x *ProtoTokenChoice) Reset() { *x = ProtoTokenChoice{} - mi := &file_core_types_proto_block_proto_msgTypes[38] + mi := &file_core_types_proto_block_proto_msgTypes[40] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2531,7 +2629,7 @@ func (x *ProtoTokenChoice) String() string { func (*ProtoTokenChoice) ProtoMessage() {} func (x *ProtoTokenChoice) ProtoReflect() protoreflect.Message { - mi := &file_core_types_proto_block_proto_msgTypes[38] + mi := &file_core_types_proto_block_proto_msgTypes[40] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2544,7 +2642,7 @@ func (x *ProtoTokenChoice) ProtoReflect() protoreflect.Message { // Deprecated: Use ProtoTokenChoice.ProtoReflect.Descriptor instead. func (*ProtoTokenChoice) Descriptor() ([]byte, []int) { - return file_core_types_proto_block_proto_rawDescGZIP(), []int{38} + return file_core_types_proto_block_proto_rawDescGZIP(), []int{40} } func (x *ProtoTokenChoice) GetQuai() uint64 { @@ -2579,7 +2677,7 @@ type ProtoBetas struct { func (x *ProtoBetas) Reset() { *x = ProtoBetas{} - mi := &file_core_types_proto_block_proto_msgTypes[39] + mi := &file_core_types_proto_block_proto_msgTypes[41] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2591,7 +2689,7 @@ func (x *ProtoBetas) String() string { func (*ProtoBetas) ProtoMessage() {} func (x *ProtoBetas) ProtoReflect() protoreflect.Message { - mi := &file_core_types_proto_block_proto_msgTypes[39] + mi := &file_core_types_proto_block_proto_msgTypes[41] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2604,7 +2702,7 @@ func (x *ProtoBetas) ProtoReflect() protoreflect.Message { // Deprecated: Use ProtoBetas.ProtoReflect.Descriptor instead. func (*ProtoBetas) Descriptor() ([]byte, []int) { - return file_core_types_proto_block_proto_rawDescGZIP(), []int{39} + return file_core_types_proto_block_proto_rawDescGZIP(), []int{41} } func (x *ProtoBetas) GetBeta0() []byte { @@ -2632,7 +2730,7 @@ type ProtoLockup struct { func (x *ProtoLockup) Reset() { *x = ProtoLockup{} - mi := &file_core_types_proto_block_proto_msgTypes[40] + mi := &file_core_types_proto_block_proto_msgTypes[42] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2644,7 +2742,7 @@ func (x *ProtoLockup) String() string { func (*ProtoLockup) ProtoMessage() {} func (x *ProtoLockup) ProtoReflect() protoreflect.Message { - mi := &file_core_types_proto_block_proto_msgTypes[40] + mi := &file_core_types_proto_block_proto_msgTypes[42] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2657,7 +2755,7 @@ func (x *ProtoLockup) ProtoReflect() protoreflect.Message { // Deprecated: Use ProtoLockup.ProtoReflect.Descriptor instead. func (*ProtoLockup) Descriptor() ([]byte, []int) { - return file_core_types_proto_block_proto_rawDescGZIP(), []int{40} + return file_core_types_proto_block_proto_rawDescGZIP(), []int{42} } func (x *ProtoLockup) GetValue() []byte { @@ -2684,7 +2782,7 @@ type ProtoLockups struct { func (x *ProtoLockups) Reset() { *x = ProtoLockups{} - mi := &file_core_types_proto_block_proto_msgTypes[41] + mi := &file_core_types_proto_block_proto_msgTypes[43] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2696,7 +2794,7 @@ func (x *ProtoLockups) String() string { func (*ProtoLockups) ProtoMessage() {} func (x *ProtoLockups) ProtoReflect() protoreflect.Message { - mi := &file_core_types_proto_block_proto_msgTypes[41] + mi := &file_core_types_proto_block_proto_msgTypes[43] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2709,7 +2807,7 @@ func (x *ProtoLockups) ProtoReflect() protoreflect.Message { // Deprecated: Use ProtoLockups.ProtoReflect.Descriptor instead. func (*ProtoLockups) Descriptor() ([]byte, []int) { - return file_core_types_proto_block_proto_rawDescGZIP(), []int{41} + return file_core_types_proto_block_proto_rawDescGZIP(), []int{43} } func (x *ProtoLockups) GetLockups() []*ProtoLockup { @@ -3237,51 +3335,60 @@ var file_core_types_proto_block_proto_rawDesc = []byte{ 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x53, 0x70, 0x65, 0x6e, 0x74, 0x55, 0x54, 0x58, 0x4f, 0x52, 0x06, 0x73, 0x75, 0x74, 0x78, 0x6f, 0x73, 0x22, 0x1f, 0x0a, 0x09, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x4b, 0x65, 0x79, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x6b, 0x65, 0x79, 0x73, - 0x18, 0x01, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x04, 0x6b, 0x65, 0x79, 0x73, 0x22, 0x99, 0x01, 0x0a, - 0x0f, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x54, 0x72, 0x69, 0x6d, 0x44, 0x65, 0x70, 0x74, 0x68, 0x73, - 0x12, 0x47, 0x0a, 0x0b, 0x74, 0x72, 0x69, 0x6d, 0x5f, 0x64, 0x65, 0x70, 0x74, 0x68, 0x73, 0x18, - 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x50, 0x72, - 0x6f, 0x74, 0x6f, 0x54, 0x72, 0x69, 0x6d, 0x44, 0x65, 0x70, 0x74, 0x68, 0x73, 0x2e, 0x54, 0x72, - 0x69, 0x6d, 0x44, 0x65, 0x70, 0x74, 0x68, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0a, 0x74, - 0x72, 0x69, 0x6d, 0x44, 0x65, 0x70, 0x74, 0x68, 0x73, 0x1a, 0x3d, 0x0a, 0x0f, 0x54, 0x72, 0x69, - 0x6d, 0x44, 0x65, 0x70, 0x74, 0x68, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, - 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, - 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x76, - 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x61, 0x0a, 0x13, 0x50, 0x72, 0x6f, 0x74, - 0x6f, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x43, 0x68, 0x6f, 0x69, 0x63, 0x65, 0x53, 0x65, 0x74, 0x12, - 0x4a, 0x0a, 0x12, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x5f, 0x63, 0x68, 0x6f, 0x69, 0x63, 0x65, 0x5f, - 0x61, 0x72, 0x72, 0x61, 0x79, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x62, 0x6c, - 0x6f, 0x63, 0x6b, 0x2e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x43, 0x68, - 0x6f, 0x69, 0x63, 0x65, 0x41, 0x72, 0x72, 0x61, 0x79, 0x52, 0x10, 0x74, 0x6f, 0x6b, 0x65, 0x6e, - 0x43, 0x68, 0x6f, 0x69, 0x63, 0x65, 0x41, 0x72, 0x72, 0x61, 0x79, 0x22, 0x6c, 0x0a, 0x15, 0x50, - 0x72, 0x6f, 0x74, 0x6f, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x43, 0x68, 0x6f, 0x69, 0x63, 0x65, 0x41, - 0x72, 0x72, 0x61, 0x79, 0x12, 0x41, 0x0a, 0x0d, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x5f, 0x63, 0x68, - 0x6f, 0x69, 0x63, 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x62, 0x6c, - 0x6f, 0x63, 0x6b, 0x2e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x43, 0x68, - 0x6f, 0x69, 0x63, 0x65, 0x48, 0x00, 0x52, 0x0c, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x43, 0x68, 0x6f, - 0x69, 0x63, 0x65, 0x73, 0x88, 0x01, 0x01, 0x42, 0x10, 0x0a, 0x0e, 0x5f, 0x74, 0x6f, 0x6b, 0x65, - 0x6e, 0x5f, 0x63, 0x68, 0x6f, 0x69, 0x63, 0x65, 0x73, 0x22, 0x4a, 0x0a, 0x10, 0x50, 0x72, 0x6f, - 0x74, 0x6f, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x43, 0x68, 0x6f, 0x69, 0x63, 0x65, 0x12, 0x12, 0x0a, - 0x04, 0x71, 0x75, 0x61, 0x69, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x04, 0x71, 0x75, 0x61, - 0x69, 0x12, 0x0e, 0x0a, 0x02, 0x71, 0x69, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x02, 0x71, - 0x69, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x69, 0x66, 0x66, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, - 0x04, 0x64, 0x69, 0x66, 0x66, 0x22, 0x38, 0x0a, 0x0a, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x42, 0x65, - 0x74, 0x61, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x62, 0x65, 0x74, 0x61, 0x30, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x0c, 0x52, 0x05, 0x62, 0x65, 0x74, 0x61, 0x30, 0x12, 0x14, 0x0a, 0x05, 0x62, 0x65, 0x74, - 0x61, 0x31, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x62, 0x65, 0x74, 0x61, 0x31, 0x22, - 0x48, 0x0a, 0x0b, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x4c, 0x6f, 0x63, 0x6b, 0x75, 0x70, 0x12, 0x14, - 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x76, - 0x61, 0x6c, 0x75, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x75, 0x6e, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x68, - 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0c, 0x75, 0x6e, 0x6c, - 0x6f, 0x63, 0x6b, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x22, 0x3c, 0x0a, 0x0c, 0x50, 0x72, 0x6f, - 0x74, 0x6f, 0x4c, 0x6f, 0x63, 0x6b, 0x75, 0x70, 0x73, 0x12, 0x2c, 0x0a, 0x07, 0x6c, 0x6f, 0x63, - 0x6b, 0x75, 0x70, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x62, 0x6c, 0x6f, - 0x63, 0x6b, 0x2e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x4c, 0x6f, 0x63, 0x6b, 0x75, 0x70, 0x52, 0x07, - 0x6c, 0x6f, 0x63, 0x6b, 0x75, 0x70, 0x73, 0x42, 0x33, 0x5a, 0x31, 0x67, 0x69, 0x74, 0x68, 0x75, - 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x64, 0x6f, 0x6d, 0x69, 0x6e, 0x61, 0x6e, 0x74, 0x2d, 0x73, - 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x69, 0x65, 0x73, 0x2f, 0x67, 0x6f, 0x2d, 0x71, 0x75, 0x61, - 0x69, 0x2f, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x62, 0x06, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x33, + 0x18, 0x01, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x04, 0x6b, 0x65, 0x79, 0x73, 0x22, 0x37, 0x0a, 0x0d, + 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x4b, 0x65, 0x79, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x10, 0x0a, + 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, + 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x52, 0x0a, 0x12, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x4b, 0x65, + 0x79, 0x73, 0x41, 0x6e, 0x64, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x12, 0x3c, 0x0a, 0x0f, 0x6b, + 0x65, 0x79, 0x73, 0x5f, 0x61, 0x6e, 0x64, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x18, 0x01, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x50, 0x72, 0x6f, + 0x74, 0x6f, 0x4b, 0x65, 0x79, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0d, 0x6b, 0x65, 0x79, 0x73, + 0x41, 0x6e, 0x64, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x22, 0x99, 0x01, 0x0a, 0x0f, 0x50, 0x72, + 0x6f, 0x74, 0x6f, 0x54, 0x72, 0x69, 0x6d, 0x44, 0x65, 0x70, 0x74, 0x68, 0x73, 0x12, 0x47, 0x0a, + 0x0b, 0x74, 0x72, 0x69, 0x6d, 0x5f, 0x64, 0x65, 0x70, 0x74, 0x68, 0x73, 0x18, 0x01, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x50, 0x72, 0x6f, 0x74, 0x6f, + 0x54, 0x72, 0x69, 0x6d, 0x44, 0x65, 0x70, 0x74, 0x68, 0x73, 0x2e, 0x54, 0x72, 0x69, 0x6d, 0x44, + 0x65, 0x70, 0x74, 0x68, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0a, 0x74, 0x72, 0x69, 0x6d, + 0x44, 0x65, 0x70, 0x74, 0x68, 0x73, 0x1a, 0x3d, 0x0a, 0x0f, 0x54, 0x72, 0x69, 0x6d, 0x44, 0x65, + 0x70, 0x74, 0x68, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, + 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x61, 0x0a, 0x13, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x54, 0x6f, + 0x6b, 0x65, 0x6e, 0x43, 0x68, 0x6f, 0x69, 0x63, 0x65, 0x53, 0x65, 0x74, 0x12, 0x4a, 0x0a, 0x12, + 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x5f, 0x63, 0x68, 0x6f, 0x69, 0x63, 0x65, 0x5f, 0x61, 0x72, 0x72, + 0x61, 0x79, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, + 0x2e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x43, 0x68, 0x6f, 0x69, 0x63, + 0x65, 0x41, 0x72, 0x72, 0x61, 0x79, 0x52, 0x10, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x43, 0x68, 0x6f, + 0x69, 0x63, 0x65, 0x41, 0x72, 0x72, 0x61, 0x79, 0x22, 0x6c, 0x0a, 0x15, 0x50, 0x72, 0x6f, 0x74, + 0x6f, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x43, 0x68, 0x6f, 0x69, 0x63, 0x65, 0x41, 0x72, 0x72, 0x61, + 0x79, 0x12, 0x41, 0x0a, 0x0d, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x5f, 0x63, 0x68, 0x6f, 0x69, 0x63, + 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, + 0x2e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x43, 0x68, 0x6f, 0x69, 0x63, + 0x65, 0x48, 0x00, 0x52, 0x0c, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x43, 0x68, 0x6f, 0x69, 0x63, 0x65, + 0x73, 0x88, 0x01, 0x01, 0x42, 0x10, 0x0a, 0x0e, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x5f, 0x63, + 0x68, 0x6f, 0x69, 0x63, 0x65, 0x73, 0x22, 0x4a, 0x0a, 0x10, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x54, + 0x6f, 0x6b, 0x65, 0x6e, 0x43, 0x68, 0x6f, 0x69, 0x63, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x71, 0x75, + 0x61, 0x69, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x04, 0x71, 0x75, 0x61, 0x69, 0x12, 0x0e, + 0x0a, 0x02, 0x71, 0x69, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x02, 0x71, 0x69, 0x12, 0x12, + 0x0a, 0x04, 0x64, 0x69, 0x66, 0x66, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x64, 0x69, + 0x66, 0x66, 0x22, 0x38, 0x0a, 0x0a, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x42, 0x65, 0x74, 0x61, 0x73, + 0x12, 0x14, 0x0a, 0x05, 0x62, 0x65, 0x74, 0x61, 0x30, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, + 0x05, 0x62, 0x65, 0x74, 0x61, 0x30, 0x12, 0x14, 0x0a, 0x05, 0x62, 0x65, 0x74, 0x61, 0x31, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x62, 0x65, 0x74, 0x61, 0x31, 0x22, 0x48, 0x0a, 0x0b, + 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x4c, 0x6f, 0x63, 0x6b, 0x75, 0x70, 0x12, 0x14, 0x0a, 0x05, 0x76, + 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x75, 0x6e, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x68, 0x65, 0x69, 0x67, + 0x68, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0c, 0x75, 0x6e, 0x6c, 0x6f, 0x63, 0x6b, + 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x22, 0x3c, 0x0a, 0x0c, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x4c, + 0x6f, 0x63, 0x6b, 0x75, 0x70, 0x73, 0x12, 0x2c, 0x0a, 0x07, 0x6c, 0x6f, 0x63, 0x6b, 0x75, 0x70, + 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, + 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x4c, 0x6f, 0x63, 0x6b, 0x75, 0x70, 0x52, 0x07, 0x6c, 0x6f, 0x63, + 0x6b, 0x75, 0x70, 0x73, 0x42, 0x33, 0x5a, 0x31, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, + 0x6f, 0x6d, 0x2f, 0x64, 0x6f, 0x6d, 0x69, 0x6e, 0x61, 0x6e, 0x74, 0x2d, 0x73, 0x74, 0x72, 0x61, + 0x74, 0x65, 0x67, 0x69, 0x65, 0x73, 0x2f, 0x67, 0x6f, 0x2d, 0x71, 0x75, 0x61, 0x69, 0x2f, 0x63, + 0x6f, 0x72, 0x65, 0x2f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x33, } var ( @@ -3296,7 +3403,7 @@ func file_core_types_proto_block_proto_rawDescGZIP() []byte { return file_core_types_proto_block_proto_rawDescData } -var file_core_types_proto_block_proto_msgTypes = make([]protoimpl.MessageInfo, 43) +var file_core_types_proto_block_proto_msgTypes = make([]protoimpl.MessageInfo, 45) var file_core_types_proto_block_proto_goTypes = []any{ (*ProtoHeader)(nil), // 0: block.ProtoHeader (*ProtoTransaction)(nil), // 1: block.ProtoTransaction @@ -3333,58 +3440,60 @@ var file_core_types_proto_block_proto_goTypes = []any{ (*ProtoSpentUTXO)(nil), // 32: block.ProtoSpentUTXO (*ProtoSpentUTXOs)(nil), // 33: block.ProtoSpentUTXOs (*ProtoKeys)(nil), // 34: block.ProtoKeys - (*ProtoTrimDepths)(nil), // 35: block.ProtoTrimDepths - (*ProtoTokenChoiceSet)(nil), // 36: block.ProtoTokenChoiceSet - (*ProtoTokenChoiceArray)(nil), // 37: block.ProtoTokenChoiceArray - (*ProtoTokenChoice)(nil), // 38: block.ProtoTokenChoice - (*ProtoBetas)(nil), // 39: block.ProtoBetas - (*ProtoLockup)(nil), // 40: block.ProtoLockup - (*ProtoLockups)(nil), // 41: block.ProtoLockups - nil, // 42: block.ProtoTrimDepths.TrimDepthsEntry - (*common.ProtoHash)(nil), // 43: common.ProtoHash - (*common.ProtoLocation)(nil), // 44: common.ProtoLocation - (*common.ProtoAddress)(nil), // 45: common.ProtoAddress - (*common.ProtoHashes)(nil), // 46: common.ProtoHashes + (*ProtoKeyValue)(nil), // 35: block.ProtoKeyValue + (*ProtoKeysAndValues)(nil), // 36: block.ProtoKeysAndValues + (*ProtoTrimDepths)(nil), // 37: block.ProtoTrimDepths + (*ProtoTokenChoiceSet)(nil), // 38: block.ProtoTokenChoiceSet + (*ProtoTokenChoiceArray)(nil), // 39: block.ProtoTokenChoiceArray + (*ProtoTokenChoice)(nil), // 40: block.ProtoTokenChoice + (*ProtoBetas)(nil), // 41: block.ProtoBetas + (*ProtoLockup)(nil), // 42: block.ProtoLockup + (*ProtoLockups)(nil), // 43: block.ProtoLockups + nil, // 44: block.ProtoTrimDepths.TrimDepthsEntry + (*common.ProtoHash)(nil), // 45: common.ProtoHash + (*common.ProtoLocation)(nil), // 46: common.ProtoLocation + (*common.ProtoAddress)(nil), // 47: common.ProtoAddress + (*common.ProtoHashes)(nil), // 48: common.ProtoHashes } var file_core_types_proto_block_proto_depIdxs = []int32{ - 43, // 0: block.ProtoHeader.parent_hash:type_name -> common.ProtoHash - 43, // 1: block.ProtoHeader.uncle_hash:type_name -> common.ProtoHash - 43, // 2: block.ProtoHeader.evm_root:type_name -> common.ProtoHash - 43, // 3: block.ProtoHeader.tx_hash:type_name -> common.ProtoHash - 43, // 4: block.ProtoHeader.outbound_etx_hash:type_name -> common.ProtoHash - 43, // 5: block.ProtoHeader.etx_rollup_hash:type_name -> common.ProtoHash - 43, // 6: block.ProtoHeader.manifest_hash:type_name -> common.ProtoHash - 43, // 7: block.ProtoHeader.receipt_hash:type_name -> common.ProtoHash - 44, // 8: block.ProtoHeader.location:type_name -> common.ProtoLocation - 43, // 9: block.ProtoHeader.mix_hash:type_name -> common.ProtoHash - 43, // 10: block.ProtoHeader.utxo_root:type_name -> common.ProtoHash - 43, // 11: block.ProtoHeader.etx_set_root:type_name -> common.ProtoHash - 43, // 12: block.ProtoHeader.etx_eligible_slices:type_name -> common.ProtoHash - 43, // 13: block.ProtoHeader.prime_terminus_hash:type_name -> common.ProtoHash - 43, // 14: block.ProtoHeader.interlink_root_hash:type_name -> common.ProtoHash + 45, // 0: block.ProtoHeader.parent_hash:type_name -> common.ProtoHash + 45, // 1: block.ProtoHeader.uncle_hash:type_name -> common.ProtoHash + 45, // 2: block.ProtoHeader.evm_root:type_name -> common.ProtoHash + 45, // 3: block.ProtoHeader.tx_hash:type_name -> common.ProtoHash + 45, // 4: block.ProtoHeader.outbound_etx_hash:type_name -> common.ProtoHash + 45, // 5: block.ProtoHeader.etx_rollup_hash:type_name -> common.ProtoHash + 45, // 6: block.ProtoHeader.manifest_hash:type_name -> common.ProtoHash + 45, // 7: block.ProtoHeader.receipt_hash:type_name -> common.ProtoHash + 46, // 8: block.ProtoHeader.location:type_name -> common.ProtoLocation + 45, // 9: block.ProtoHeader.mix_hash:type_name -> common.ProtoHash + 45, // 10: block.ProtoHeader.utxo_root:type_name -> common.ProtoHash + 45, // 11: block.ProtoHeader.etx_set_root:type_name -> common.ProtoHash + 45, // 12: block.ProtoHeader.etx_eligible_slices:type_name -> common.ProtoHash + 45, // 13: block.ProtoHeader.prime_terminus_hash:type_name -> common.ProtoHash + 45, // 14: block.ProtoHeader.interlink_root_hash:type_name -> common.ProtoHash 5, // 15: block.ProtoTransaction.access_list:type_name -> block.ProtoAccessList - 43, // 16: block.ProtoTransaction.originating_tx_hash:type_name -> common.ProtoHash + 45, // 16: block.ProtoTransaction.originating_tx_hash:type_name -> common.ProtoHash 25, // 17: block.ProtoTransaction.tx_ins:type_name -> block.ProtoTxIns 26, // 18: block.ProtoTransaction.tx_outs:type_name -> block.ProtoTxOuts - 43, // 19: block.ProtoTransaction.parent_hash:type_name -> common.ProtoHash - 43, // 20: block.ProtoTransaction.mix_hash:type_name -> common.ProtoHash + 45, // 19: block.ProtoTransaction.parent_hash:type_name -> common.ProtoHash + 45, // 20: block.ProtoTransaction.mix_hash:type_name -> common.ProtoHash 1, // 21: block.ProtoTransactions.transactions:type_name -> block.ProtoTransaction 0, // 22: block.ProtoHeaders.headers:type_name -> block.ProtoHeader - 43, // 23: block.ProtoManifest.manifest:type_name -> common.ProtoHash + 45, // 23: block.ProtoManifest.manifest:type_name -> common.ProtoHash 15, // 24: block.ProtoAccessList.access_tuples:type_name -> block.ProtoAccessTuple - 43, // 25: block.ProtoWorkObjectHeader.header_hash:type_name -> common.ProtoHash - 43, // 26: block.ProtoWorkObjectHeader.parent_hash:type_name -> common.ProtoHash - 43, // 27: block.ProtoWorkObjectHeader.tx_hash:type_name -> common.ProtoHash - 44, // 28: block.ProtoWorkObjectHeader.location:type_name -> common.ProtoLocation - 43, // 29: block.ProtoWorkObjectHeader.mix_hash:type_name -> common.ProtoHash - 45, // 30: block.ProtoWorkObjectHeader.primary_coinbase:type_name -> common.ProtoAddress + 45, // 25: block.ProtoWorkObjectHeader.header_hash:type_name -> common.ProtoHash + 45, // 26: block.ProtoWorkObjectHeader.parent_hash:type_name -> common.ProtoHash + 45, // 27: block.ProtoWorkObjectHeader.tx_hash:type_name -> common.ProtoHash + 46, // 28: block.ProtoWorkObjectHeader.location:type_name -> common.ProtoLocation + 45, // 29: block.ProtoWorkObjectHeader.mix_hash:type_name -> common.ProtoHash + 47, // 30: block.ProtoWorkObjectHeader.primary_coinbase:type_name -> common.ProtoAddress 6, // 31: block.ProtoWorkObjectHeaders.wo_headers:type_name -> block.ProtoWorkObjectHeader 0, // 32: block.ProtoWorkObjectBody.header:type_name -> block.ProtoHeader 2, // 33: block.ProtoWorkObjectBody.transactions:type_name -> block.ProtoTransactions 7, // 34: block.ProtoWorkObjectBody.uncles:type_name -> block.ProtoWorkObjectHeaders 2, // 35: block.ProtoWorkObjectBody.outbound_etxs:type_name -> block.ProtoTransactions 4, // 36: block.ProtoWorkObjectBody.manifest:type_name -> block.ProtoManifest - 46, // 37: block.ProtoWorkObjectBody.interlink_hashes:type_name -> common.ProtoHashes + 48, // 37: block.ProtoWorkObjectBody.interlink_hashes:type_name -> common.ProtoHashes 6, // 38: block.ProtoWorkObject.wo_header:type_name -> block.ProtoWorkObjectHeader 8, // 39: block.ProtoWorkObject.wo_body:type_name -> block.ProtoWorkObjectBody 1, // 40: block.ProtoWorkObject.tx:type_name -> block.ProtoTransaction @@ -3393,19 +3502,19 @@ var file_core_types_proto_block_proto_depIdxs = []int32{ 11, // 43: block.ProtoWorkObjectBlocksView.work_objects:type_name -> block.ProtoWorkObjectBlockView 9, // 44: block.ProtoWorkObjectHeaderView.work_object:type_name -> block.ProtoWorkObject 9, // 45: block.ProtoWorkObjectShareView.work_object:type_name -> block.ProtoWorkObject - 43, // 46: block.ProtoAccessTuple.storage_key:type_name -> common.ProtoHash + 45, // 46: block.ProtoAccessTuple.storage_key:type_name -> common.ProtoHash 19, // 47: block.ProtoReceiptForStorage.logs:type_name -> block.ProtoLogsForStorage - 43, // 48: block.ProtoReceiptForStorage.tx_hash:type_name -> common.ProtoHash - 45, // 49: block.ProtoReceiptForStorage.contract_address:type_name -> common.ProtoAddress + 45, // 48: block.ProtoReceiptForStorage.tx_hash:type_name -> common.ProtoHash + 47, // 49: block.ProtoReceiptForStorage.contract_address:type_name -> common.ProtoAddress 2, // 50: block.ProtoReceiptForStorage.outbound_etxs:type_name -> block.ProtoTransactions 16, // 51: block.ProtoReceiptsForStorage.receipts:type_name -> block.ProtoReceiptForStorage - 45, // 52: block.ProtoLogForStorage.address:type_name -> common.ProtoAddress - 43, // 53: block.ProtoLogForStorage.topics:type_name -> common.ProtoHash + 47, // 52: block.ProtoLogForStorage.address:type_name -> common.ProtoAddress + 45, // 53: block.ProtoLogForStorage.topics:type_name -> common.ProtoHash 18, // 54: block.ProtoLogsForStorage.logs:type_name -> block.ProtoLogForStorage 9, // 55: block.ProtoPendingHeader.wo:type_name -> block.ProtoWorkObject 21, // 56: block.ProtoPendingHeader.termini:type_name -> block.ProtoTermini - 43, // 57: block.ProtoTermini.dom_termini:type_name -> common.ProtoHash - 43, // 58: block.ProtoTermini.sub_termini:type_name -> common.ProtoHash + 45, // 57: block.ProtoTermini.dom_termini:type_name -> common.ProtoHash + 45, // 58: block.ProtoTermini.sub_termini:type_name -> common.ProtoHash 9, // 59: block.ProtoPendingEtxs.header:type_name -> block.ProtoWorkObject 2, // 60: block.ProtoPendingEtxs.outbound_etxs:type_name -> block.ProtoTransactions 9, // 61: block.ProtoPendingEtxsRollup.header:type_name -> block.ProtoWorkObject @@ -3413,21 +3522,22 @@ var file_core_types_proto_block_proto_depIdxs = []int32{ 27, // 63: block.ProtoTxIns.tx_ins:type_name -> block.ProtoTxIn 29, // 64: block.ProtoTxOuts.tx_outs:type_name -> block.ProtoTxOut 28, // 65: block.ProtoTxIn.previous_out_point:type_name -> block.ProtoOutPoint - 43, // 66: block.ProtoOutPoint.hash:type_name -> common.ProtoHash - 43, // 67: block.ProtoOutPointAndDenomination.hash:type_name -> common.ProtoHash + 45, // 66: block.ProtoOutPoint.hash:type_name -> common.ProtoHash + 45, // 67: block.ProtoOutPointAndDenomination.hash:type_name -> common.ProtoHash 30, // 68: block.ProtoAddressOutPoints.out_points:type_name -> block.ProtoOutPointAndDenomination 28, // 69: block.ProtoSpentUTXO.outpoint:type_name -> block.ProtoOutPoint 29, // 70: block.ProtoSpentUTXO.sutxo:type_name -> block.ProtoTxOut 32, // 71: block.ProtoSpentUTXOs.sutxos:type_name -> block.ProtoSpentUTXO - 42, // 72: block.ProtoTrimDepths.trim_depths:type_name -> block.ProtoTrimDepths.TrimDepthsEntry - 37, // 73: block.ProtoTokenChoiceSet.token_choice_array:type_name -> block.ProtoTokenChoiceArray - 38, // 74: block.ProtoTokenChoiceArray.token_choices:type_name -> block.ProtoTokenChoice - 40, // 75: block.ProtoLockups.lockups:type_name -> block.ProtoLockup - 76, // [76:76] is the sub-list for method output_type - 76, // [76:76] is the sub-list for method input_type - 76, // [76:76] is the sub-list for extension type_name - 76, // [76:76] is the sub-list for extension extendee - 0, // [0:76] is the sub-list for field type_name + 35, // 72: block.ProtoKeysAndValues.keys_and_values:type_name -> block.ProtoKeyValue + 44, // 73: block.ProtoTrimDepths.trim_depths:type_name -> block.ProtoTrimDepths.TrimDepthsEntry + 39, // 74: block.ProtoTokenChoiceSet.token_choice_array:type_name -> block.ProtoTokenChoiceArray + 40, // 75: block.ProtoTokenChoiceArray.token_choices:type_name -> block.ProtoTokenChoice + 42, // 76: block.ProtoLockups.lockups:type_name -> block.ProtoLockup + 77, // [77:77] is the sub-list for method output_type + 77, // [77:77] is the sub-list for method input_type + 77, // [77:77] is the sub-list for extension type_name + 77, // [77:77] is the sub-list for extension extendee + 0, // [0:77] is the sub-list for field type_name } func init() { file_core_types_proto_block_proto_init() } @@ -3452,14 +3562,14 @@ func file_core_types_proto_block_proto_init() { file_core_types_proto_block_proto_msgTypes[29].OneofWrappers = []any{} file_core_types_proto_block_proto_msgTypes[30].OneofWrappers = []any{} file_core_types_proto_block_proto_msgTypes[32].OneofWrappers = []any{} - file_core_types_proto_block_proto_msgTypes[37].OneofWrappers = []any{} + file_core_types_proto_block_proto_msgTypes[39].OneofWrappers = []any{} type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_core_types_proto_block_proto_rawDesc, NumEnums: 0, - NumMessages: 43, + NumMessages: 45, NumExtensions: 0, NumServices: 0, }, diff --git a/core/types/proto_block.proto b/core/types/proto_block.proto index c4e208c515..f960795cb0 100644 --- a/core/types/proto_block.proto +++ b/core/types/proto_block.proto @@ -223,6 +223,14 @@ message ProtoKeys { repeated bytes keys = 1; } +message ProtoKeyValue { + bytes key = 1; + bytes value = 2; +} +message ProtoKeysAndValues { + repeated ProtoKeyValue keys_and_values = 1; +} + message ProtoTrimDepths { map trim_depths = 1; } diff --git a/core/types/receipt.go b/core/types/receipt.go index a3564d7248..153a6a27d4 100644 --- a/core/types/receipt.go +++ b/core/types/receipt.go @@ -73,6 +73,10 @@ type Receipt struct { BlockNumber *big.Int `json:"blockNumber,omitempty"` TransactionIndex uint `json:"transactionIndex"` OutboundEtxs Transactions `json:"outboundEtxs"` + + // Cached values: These fields are used to cache values that are expensive to compute and are not stored in the database. + CoinbaseLockupDeletedHashes []*common.Hash + CoinbaseLockupsDeleted map[[47]byte][]byte } type receiptMarshaling struct { diff --git a/core/vm/contracts.go b/core/vm/contracts.go index a9fdccab4b..5938296577 100644 --- a/core/vm/contracts.go +++ b/core/vm/contracts.go @@ -610,6 +610,40 @@ func ABIEncodeLockupData(trancheUnlockHeight uint32, balance *big.Int, elements return encoded, nil } +func GetAllLockupData(db ethdb.Database, ownerContract, beneficiaryMiner common.Address, location common.Location, logger *log.Logger) (map[string]map[string][]interface{}, error) { + prefix := append(rawdb.CoinbaseLockupPrefix, ownerContract.Bytes()...) + prefix = append(prefix, beneficiaryMiner.Bytes()...) + it := db.NewIterator(prefix, nil) + batch := db.NewBatch() + defer it.Release() + epochToLockupByteToLockupMap := make(map[string]map[string][]interface{}) + for it.Next() { + key := it.Key() + if len(key) != rawdb.CoinbaseLockupKeyLength { + continue + } + _, _, lockupByte, epoch, err := rawdb.ReverseCoinbaseLockupKey(key, location) + if err != nil { + return nil, err + } + balance, trancheUnlockHeight, elements, delegate := rawdb.ReadCoinbaseLockup(db, batch, ownerContract, beneficiaryMiner, lockupByte, epoch) + if trancheUnlockHeight == 0 { + logger.Errorf("lockup is empty: ownerContract=%v, beneficiaryMiner=%v, lockupByte=%v, epoch=%v", ownerContract, beneficiaryMiner, lockupByte, epoch) + } + jsonLockup := map[string]interface{}{ + "balance": balance, + "trancheUnlockHeight": trancheUnlockHeight, + "elements": elements, + "delegate": delegate, + } + if _, ok := epochToLockupByteToLockupMap[fmt.Sprintf("%d", epoch)]; !ok { + epochToLockupByteToLockupMap[fmt.Sprintf("%d", epoch)] = make(map[string][]interface{}) + } + epochToLockupByteToLockupMap[fmt.Sprintf("%d", epoch)][fmt.Sprintf("%d", lockupByte)] = append(epochToLockupByteToLockupMap[fmt.Sprintf("%d", epoch)][fmt.Sprintf("%d", lockupByte)], jsonLockup) + } + return epochToLockupByteToLockupMap, nil +} + func ClaimCoinbaseLockup(evm *EVM, ownerContract common.Address, currentHeight uint64, gas *uint64, input []byte) error { // Ensure msg.sender is ownerContract // Input should be tightly packed 33 bytes if len(input) != 33 { diff --git a/core/vm/evm.go b/core/vm/evm.go index ca6420bcb4..17d1340798 100644 --- a/core/vm/evm.go +++ b/core/vm/evm.go @@ -712,6 +712,7 @@ func (evm *EVM) GetLatestMinerEpoch() (uint32, error) { return evm.StateDB.GetLa func (evm *EVM) ResetCoinbasesDeleted() { evm.CoinbasesDeleted = make(map[[47]byte][]byte) + evm.CoinbaseDeletedHashes = make([]*common.Hash, 0) } func (evm *EVM) UndoCoinbasesDeleted() { diff --git a/internal/quaiapi/quai_api.go b/internal/quaiapi/quai_api.go index dd0bc4f2d4..7e252500dd 100644 --- a/internal/quaiapi/quai_api.go +++ b/internal/quaiapi/quai_api.go @@ -30,6 +30,7 @@ import ( "github.com/dominant-strategies/go-quai/core" "github.com/dominant-strategies/go-quai/core/rawdb" "github.com/dominant-strategies/go-quai/core/types" + "github.com/dominant-strategies/go-quai/core/vm" "github.com/dominant-strategies/go-quai/crypto" "github.com/dominant-strategies/go-quai/log" "github.com/dominant-strategies/go-quai/metrics_config" @@ -271,6 +272,18 @@ func (s *PublicBlockChainQuaiAPI) GetLockupsByAddressAndRange(ctx context.Contex return jsonLockups, nil } +func (s *PublicBlockChainQuaiAPI) GetLockupsForContractAndMiner(ctx context.Context, ownerContract, beneficiaryMiner common.Address) (map[string]map[string][]interface{}, error) { + _, err := ownerContract.InternalAndQuaiAddress() + if err != nil { + return nil, err + } + _, err = beneficiaryMiner.InternalAddress() + if err != nil { + return nil, err + } + return vm.GetAllLockupData(s.b.Database(), ownerContract, beneficiaryMiner, s.b.NodeLocation(), s.b.Logger()) +} + func (s *PublicBlockChainQuaiAPI) GetOutPointsByAddressAndRange(ctx context.Context, address common.Address, start, end hexutil.Uint64) (map[string][]interface{}, error) { if start > end { return nil, fmt.Errorf("start is greater than end")