Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

internal: add db operations to api #24739

Merged
merged 6 commits into from
Apr 27, 2022
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion cmd/geth/consolecmd_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ import (
)

const (
ipcAPIs = "admin:1.0 debug:1.0 eth:1.0 ethash:1.0 miner:1.0 net:1.0 personal:1.0 rpc:1.0 txpool:1.0 web3:1.0"
ipcAPIs = "admin:1.0 db:1.0 debug:1.0 eth:1.0 ethash:1.0 miner:1.0 net:1.0 personal:1.0 rpc:1.0 txpool:1.0 web3:1.0"
httpAPIs = "eth:1.0 net:1.0 rpc:1.0 web3:1.0"
)

Expand Down
54 changes: 54 additions & 0 deletions internal/ethapi/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -1998,6 +1998,51 @@ func (s *PublicNetAPI) Version() string {
return fmt.Sprintf("%d", s.networkVersion)
}

// PublicDbAPI exposes low-level methods for interacting with the database.
type PublicDbAPI struct {
b Backend
}

// NewPublicDbAPI creates a new instance of PublicDbAPI.
func NewPublicDbAPI(b Backend) *PublicDbAPI {
return &PublicDbAPI{b: b}
}

// Get returns the raw value of a key stored in the database.
func (api *PublicDbAPI) Get(key string) (hexutil.Bytes, error) {
blob, err := parseHexOrString(key)
if err != nil {
return nil, err
}
return api.b.ChainDb().Get(blob)
}

// Put stores a raw value under the key in the database.
func (api *PublicDbAPI) Put(key string, value hexutil.Bytes) (hexutil.Bytes, error) {
var (
ret []byte
db = api.b.ChainDb()
)
blob, err := parseHexOrString(key)
if err != nil {
return nil, err
}
data, err := db.Get(blob)
if err == nil {
ret = data
}
return ret, db.Put(blob, value)
Copy link
Member

Choose a reason for hiding this comment

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

Can we print some logs for database mutation? (for example, key value of the inserted item). I think it's fine to dump out logs for this special debug purpose API.

}

// Delete removes an item from the database.
func (api *PublicDbAPI) Delete(key string) error {
Copy link
Member

Choose a reason for hiding this comment

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

Should we return the previous value as well? So that users can see clearly what's deleted.

blob, err := parseHexOrString(key)
if err != nil {
return err
}
Copy link
Member

Choose a reason for hiding this comment

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

Can we print some logs for database mutation? (for example, the key of deleted item). I think it's fine to dump out logs for this special debug purpose API.

cc @holiman

return api.b.ChainDb().Delete(blob)
}

// checkTxFee is an internal function used to check whether the fee of
// the given transaction is _reasonable_(under the cap).
func checkTxFee(gasPrice *big.Int, gas uint64, cap float64) error {
Expand All @@ -2021,3 +2066,12 @@ func toHexSlice(b [][]byte) []string {
}
return r
}

// ParseHexOrString tries to hexdecode b, but if the prefix is missing, it instead just returns the raw bytes
func parseHexOrString(str string) ([]byte, error) {
Copy link
Member

Choose a reason for hiding this comment

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

Nitpick, perhaps we can move this function into common package, but feel free to ignore this comment.

b, err := hexutil.Decode(str)
if errors.Is(err, hexutil.ErrMissingPrefix) {
return []byte(str), nil
}
return b, err
}
5 changes: 5 additions & 0 deletions internal/ethapi/backend.go
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,11 @@ func GetAPIs(apiBackend Backend) []rpc.API {
Version: "1.0",
Service: NewPrivateAccountAPI(apiBackend, nonceLock),
Public: false,
}, {
Namespace: "db",
Version: "1.0",
Service: NewPublicDbAPI(apiBackend),
Public: true,
Copy link
Member

Choose a reason for hiding this comment

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

Perhaps we should convert it to private API? Private APIs can also be exposed(http, ws) IIUC if users specify it, Public APIs will be exposed if the API module list specified by users is empty.

},
}
}
26 changes: 26 additions & 0 deletions internal/web3ext/web3ext.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ var Modules = map[string]string{
"txpool": TxpoolJs,
"les": LESJs,
"vflux": VfluxJs,
"db": DbJS,
}

const CliqueJs = `
Expand Down Expand Up @@ -853,3 +854,28 @@ web3._extend({
]
});
`

const DbJS = `
web3._extend({
property: 'db',
methods:
[
new web3._extend.Method({
name: 'get',
call: 'db_get',
params: 1
}),
new web3._extend.Method({
name: 'put',
call: 'db_put',
params: 2
}),
new web3._extend.Method({
name: 'delete',
call: 'db_delete',
params: 1
}),
],
properties: []
});
`