-
Notifications
You must be signed in to change notification settings - Fork 771
Proposervm API #4029
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
base: master
Are you sure you want to change the base?
Proposervm API #4029
Changes from all commits
6e37eda
e250b85
463b936
79613f1
fa1802a
0e093df
43e04c8
0875cb7
7ea6ee9
3ecd42f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. | ||
// See the file LICENSE for licensing terms. | ||
|
||
package proposervm | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
|
||
"github.com/ava-labs/avalanchego/api" | ||
"github.com/ava-labs/avalanchego/ids" | ||
"github.com/ava-labs/avalanchego/utils/formatting" | ||
"github.com/ava-labs/avalanchego/utils/rpc" | ||
) | ||
|
||
var _ Client = (*client)(nil) | ||
|
||
type Client interface { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. who/what is consuming this interface? Usually in Golang, interfaces are declared where they're used, not where they're implemented. |
||
// GetProposedHeight returns the current height of this node's proposer VM. | ||
GetProposedHeight(ctx context.Context, options ...rpc.Option) (uint64, error) | ||
// GetProposerBlockWrapper returns the ProposerVM block wrapper | ||
GetProposerBlockWrapper(ctx context.Context, proposerID ids.ID, options ...rpc.Option) ([]byte, error) | ||
} | ||
|
||
type client struct { | ||
requester rpc.EndpointRequester | ||
} | ||
|
||
// NewClient returns a Client for interacting with the ProposerVM API. | ||
// The provided blockchainName should be the blockchainID or an alias (e.g. "P" for the P-Chain). | ||
func NewClient(uri string, blockchainName string) Client { | ||
return &client{ | ||
requester: rpc.NewEndpointRequester(uri + fmt.Sprintf("/ext/bc/%s/proposervm", blockchainName)), | ||
} | ||
} | ||
|
||
func (c *client) GetProposedHeight(ctx context.Context, options ...rpc.Option) (uint64, error) { | ||
res := &api.GetHeightResponse{} | ||
err := c.requester.SendRequest(ctx, "proposervm.getProposedHeight", struct{}{}, res, options...) | ||
return uint64(res.Height), err | ||
} | ||
|
||
func (c *client) GetProposerBlockWrapper(ctx context.Context, proposerID ids.ID, options ...rpc.Option) ([]byte, error) { | ||
res := &api.FormattedBlock{} | ||
if err := c.requester.SendRequest(ctx, "proposervm.getProposerBlockWrapper", &GetProposerBlockArgs{ | ||
ProposerID: proposerID, | ||
Encoding: formatting.Hex, | ||
}, res, options...); err != nil { | ||
return nil, err | ||
} | ||
return formatting.Decode(res.Encoding, res.Block) | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. can we add tests to the code in this file? |
||
// See the file LICENSE for licensing terms. | ||
Comment on lines
+1
to
+2
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The lint job did not like including |
||
|
||
package proposervm | ||
|
||
import ( | ||
"encoding/json" | ||
"fmt" | ||
"net/http" | ||
|
||
"go.uber.org/zap" | ||
|
||
"github.com/ava-labs/avalanchego/api" | ||
"github.com/ava-labs/avalanchego/ids" | ||
"github.com/ava-labs/avalanchego/utils/formatting" | ||
|
||
avajson "github.com/ava-labs/avalanchego/utils/json" | ||
) | ||
|
||
type ProposerAPI struct { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What is the reason for having the proposerVM as a field instead of just adding the functions to the proposerVM VM? If we wish to isolate the VM object then it makes sense to add two functions or (an) interface(s) with:
and then it'll be easier to test. |
||
vm *VM | ||
} | ||
|
||
cam-schultz marked this conversation as resolved.
Show resolved
Hide resolved
|
||
func (p *ProposerAPI) GetProposedHeight(_ *http.Request, _ *struct{}, reply *api.GetHeightResponse) error { | ||
p.vm.ctx.Log.Debug("API called", | ||
zap.String("service", "proposervm"), | ||
zap.String("method", "getProposedHeight"), | ||
) | ||
p.vm.ctx.Lock.Lock() | ||
defer p.vm.ctx.Lock.Unlock() | ||
|
||
reply.Height = avajson.Uint64(p.vm.lastAcceptedHeight) | ||
return nil | ||
} | ||
|
||
// GetProposerBlockArgs is the parameters supplied to the GetProposerBlockWrapper API | ||
type GetProposerBlockArgs struct { | ||
ProposerID ids.ID `json:"proposerID"` | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I added this type rather than using the existing That said, I'm not sure what the best way to actually source the "Proposer ID" in the general case, since it's not exposed by the innerVM. Similarly, an endpoint to map Block hash -> Proposer ID seems like it would break encapsulation. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The word There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The explorer uses |
||
Encoding formatting.Encoding `json:"encoding"` | ||
} | ||
|
||
func (p *ProposerAPI) GetProposerBlockWrapper(r *http.Request, args *GetProposerBlockArgs, reply *api.GetBlockResponse) error { | ||
p.vm.ctx.Log.Debug("API called", | ||
zap.String("service", "proposervm"), | ||
zap.String("method", "getProposerBlockWrapper"), | ||
zap.String("proposerID", args.ProposerID.String()), | ||
zap.String("encoding", args.Encoding.String()), | ||
) | ||
p.vm.ctx.Lock.Lock() | ||
defer p.vm.ctx.Lock.Unlock() | ||
|
||
block, err := p.vm.GetBlock(r.Context(), args.ProposerID) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. am I reading this wrong and we're actually sending back the entire proposerVM block which also contains the inner VM block? If so, is it possible to only distill the proposerVM bytes? |
||
if err != nil { | ||
return err | ||
} | ||
reply.Encoding = args.Encoding | ||
|
||
var result any | ||
if args.Encoding == formatting.JSON { | ||
result = block | ||
} else { | ||
result, err = formatting.Encode(args.Encoding, block.Bytes()) | ||
if err != nil { | ||
return fmt.Errorf("couldn't encode block %s as %s: %w", args.ProposerID, args.Encoding, err) | ||
} | ||
} | ||
|
||
reply.Block, err = json.Marshal(result) | ||
return err | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,138 @@ | ||
The ProposerVM API allows clients to fetch information about a Snowman++ chain's ProposerVM. | ||
|
||
## Endpoint | ||
|
||
``` | ||
/ext/bc/{blockchainID}/proposervm | ||
``` | ||
|
||
## Format | ||
|
||
This API uses the `json 2.0` RPC format. | ||
|
||
## Methods | ||
|
||
### `proposervm.getProposedHeight` | ||
|
||
Returns this node's current proposer VM height. | ||
|
||
**Signature:** | ||
|
||
``` | ||
proposervm.getProposedHeight() -> | ||
{ | ||
height: int, | ||
} | ||
``` | ||
|
||
**Example Call:** | ||
|
||
```sh | ||
curl -X POST --data '{ | ||
"jsonrpc": "2.0", | ||
"method": "proposervm.getProposedHeight", | ||
"params": {}, | ||
"id": 1 | ||
}' -H 'content-type:application/json;' 127.0.0.1:9650/ext/bc/P/proposervm | ||
``` | ||
|
||
**Example Response:** | ||
|
||
```json | ||
{ | ||
"jsonrpc": "2.0", | ||
"result": { | ||
"height": "56" | ||
}, | ||
"id": 1 | ||
} | ||
``` | ||
|
||
### `proposervm.getProposerBlockWrapper` | ||
|
||
Get a block's ProposerVM wrapper by its proposer ID. | ||
|
||
**Signature:** | ||
|
||
``` | ||
proposervm.getProposerBlockWrapper({ | ||
proposerID: string | ||
encoding: string // optional | ||
}) -> { | ||
block: string, | ||
encoding: string | ||
} | ||
``` | ||
|
||
**Request:** | ||
|
||
- `proposerID` is the proposer ID. It should be in cb58 format. | ||
- `encoding` is the encoding format to use. Can be either `hex` or `json`. Defaults to `hex`. | ||
|
||
#### Hex Example | ||
|
||
**Example Call:** | ||
|
||
```sh | ||
curl -X POST --data '{ | ||
"jsonrpc": "2.0", | ||
"method": "proposervm.getProposerBlockWrapper", | ||
"params": { | ||
"proposerID": "owJxcaDMaehbqoib8FRP7MuPdfGpSdXqD4hjkBtW4vcCJzr2Y", | ||
"encoding": "hex" | ||
}, | ||
"id": 1 | ||
}' -H 'content-type:application/json;' 127.0.0.1:9650/ext/bc/C/proposervm | ||
``` | ||
|
||
**Example Response:** | ||
|
||
```json | ||
{ | ||
"jsonrpc":"2.0", | ||
"result":{ | ||
"block":"0x000000000000018a9f604b26237c49e54667b80e24433512774dd6bb8cd99032e927ae141dcd0000000068597a6d00000000000000000000053b308205373082031f020900baf3b5c5c6d0d14a300d06092a864886f70d01010b0500307f310b3009060355040613025553310b300906035504080c024e59310f300d06035504070c064974686163613110300e060355040a0c074176616c616273310e300c060355040b0c054765636b6f310c300a06035504030c036176613122302006092a864886f70d01090116137374657068656e406176616c6162732e6f72673020170d3139303730323136313231395a180f33303139303731303136313231395a303a310b3009060355040613025553310b300906035504080c024e593110300e060355040a0c074176616c616273310c300a06035504030c0361766130820222300d06092a864886f70d01010105000382020f003082020a0282020100dd4e847ad276ba36e47d892014332ccf5c934c59541b2f24f9fe2642889dc107861630185fc6925626259770cfb39c382926ec8211e8790e9e9963715eee4e8786de85985a438f09e3a5099d904294834d06f8494f4e9fd4b26b0f2fe240b303ea0595a93014b776c5d036e9cc32d30696b7f94b497a5d7e32ee473f193c5882f79667d26d47f9b628d7abfb08e0047a89e2b3ea9c7077d2c0d83d983dd42cf5024f016f6c36235d3ccd056028ae9e22a34a5c927fe298b3499754e3ddb4c0cc580699df0c07219f17a2f54fefdd06d3ede2942367c6afe84e59321653cd3e55e381b7c6ba3f8b12f40421e7fe86f2ac2602a3b7610f5dc4df368aefc7dfe37e1866bf334af9ac45abcf022e161c0abf241ca4f4419b6c909c19e12fd1b990dea7e0e04cd0ab2067709894765283879670d801b7558216c41ceef7d415a267afc40fde917857fe01a24ef04cee4737403511811562e5f9dcd1a7aca55ef8583dfb130e8173d691436a76fa48f596d5dd9d12e7cebaa85dffbc166b8600ab29ce44fef31ec4145ef0a8b8c0aa8e355862f561947111ef1448a473eed5acf8f461a1bacd52ddfae38024df357ca38f628e17e2c66b3323d89773a31ad3217d5e0abc268b12bd5db8e925a8ee9c0af190f220252d5cb7549c96e462740f42b28808abe1535d0092a8d598221a2bc92d6ba54df8d489f08df68d75e408aa2718aac30203010001300d06092a864886f70d01010b050003820201009039dc03ede448c41bdb40751cfa6d1347311ad7b0427dc9356365b03774d95c319290f544d2eba303c48bdea8bcfc24cb191a88f54de045925ffad24f045fcfd36d4f126c9a1534b886dc5c0f14f1b99bf68c2a3df97854132bd15a2b539a8cb57acab79a4a2d5501de4e642fc02b1024085cb5503f851749c2630fb3507c43139423a06a48e0476bd0ac5c8cd5385bfc16a13dd4f640da7b37d2c29062bae76c7f7d6a97c5e568252d4a323f0c5fd9edc000287b6de11d938e62bef2b08b9264f27afce4a0c760f96a92bd1b77d12197cc6995a34174c3de46e7ea043973b6370b277c289a7aedf7981031e4a82c763750db084636e3e37cc89aeeeaf6ffc30fda69429bb6e9a44346604d80b640f463395e76d94458b75712f2a9ab06712cda1f0cf973bbce04e90e765a9c43321246f583c623751e400bfa1922402b8c72180e44080cc333e8a1af2b7d6b4b229397329c2e5466fff2b18d2c43e8be808af73e9cf9667ece4468e3edd342438c63ae9786deeb021972de57abf93ca0e9ae635d3f7658a0bf317058032d9940da32db4e2434a7af707ed1d9c4a4c484ddde7e4469c372e4c02d08d224ec9c1e2c287dacbacb501b7e8b89f8e2c3fe2d585f5877a69e003c0a81789fa790d29a748b16537a7d23e2e3741b635ff89786325aa839b2d674839d1ffa5b0e9a571a865a28a0ddefe6c0ef81657b9521efed5edc00000373f90370f90298a057b43873f59d6e0ff493909e8373502eaa828f0eb4d7dbe999b855f9b895d88ca01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347940100000000000000000000000000000000000000a0685dcd731e76c2e6a503df5759ab11b324f03c8f26090637ad4dbb26ad5522fba04efbaa764431eba396b9edba52f594a6660473432761931c98b49ef00467b87ea0d95b673818fa493deec414e01e610d97ee287c9421c8eff4102b1647c1a184e4b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010c83e4e1c082a4108468597a6db8560000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000880000000000000000a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421843b9aca0080808080a00000000000000000000000000000000000000000000000000000000000000000f8d0f866108534630b8a00825208948db97c7cece249c2b98bdc0226cc4c2a57bf52fc0180820a95a07ef0c6d54c839648ea6cfe191c37efc5ba9d9115695e061870b601c1ce647e75a03e066459cb0853a8d67f7b777753515b2ce627553a4d9b51b06ad6bdf3102b8ef866118534630b8a00825208948db97c7cece249c2b98bdc0226cc4c2a57bf52fc0180820a96a03a1c18eea77d4f08a29e482442ca2f2beb5bc8568e2768470ebdb6ae05382424a06e205ef2e0273c481f2e28a60e504575dba0714608601880d87906a98de41bb3c0808000000200bfcc7483e2c539c2d925a1b4eed65e2cbfae39e284be82d77ee86c078d1a1d4f54d8c46c6695d6619a589137eabcd4a8e93c94394c4d83458b122598b9d69f49f0c9e61b746ad46d91710c3475c97595d17c3ef1aa8c7e846fd8a231bdb68687a208ee752cd64ecf86288bec610688708e34d54ecb15ea4178e1dab8a74109ae1514240a08cddae9dc8ec6db17cfeffc2d0814e908e57676700c6fa3a4bbe1c84e537fd7d2f28491bf9ce3c5e57308027c198a3547ad9a23d365359b0c709c260abf6a04cdc59bcb4a65006c66c9cc2becae49e9275a2f3517260762a7b4c646121583590a25de74a924a66a43d2b1a6f09adfb664e552fc0b1b260594df57795b334c125627e112606d784790f6916dcb610f1e10a424f0ef8244cde7d2f0631e025b28d54f8a24003f3792b420a1eeb62a8a21a27e9eb7e3278b7e14dfc784e736ce2fad220ea9c2d97e98b451fd3a212b6b863a779d55a80ead284e49e0556792663e38316e7a31ac6b1915e96a1dd50924c48ffbb7d46df363baa3c8184457411577aa793cb3a9adef73301ecec8f7561f60a6187f13ed34d2e1756a7959fd5b10a4f753d07dd90022de2a2ea401e2516cd917a2a48c030e2cc0b2dfaa5dec82af18f6772462a5a58a9d128772b45f782c8a1854564158ed75531cc02d2050170de95147a8eb2b8364fb83d74722bee68e1654cf314d629599e3795617ff75c569bd", | ||
"encoding":"hex" | ||
}, | ||
"id":1 | ||
} | ||
``` | ||
|
||
#### JSON Example | ||
|
||
**Example Call:** | ||
|
||
```sh | ||
curl -X POST --data '{ | ||
"jsonrpc": "2.0", | ||
"method": "proposervm.getProposerBlockWrapper", | ||
"params": { | ||
"proposerID": "owJxcaDMaehbqoib8FRP7MuPdfGpSdXqD4hjkBtW4vcCJzr2Y", | ||
"encoding": "json" | ||
}, | ||
"id": 1 | ||
}' -H 'content-type:application/json;' 127.0.0.1:9650/ext/bc/C/proposervm | ||
``` | ||
|
||
**Example Response:** | ||
|
||
```json | ||
{ | ||
"jsonrpc":"2.0", | ||
"result":{ | ||
"block":{ | ||
"SignedBlock":{ | ||
"block":{ | ||
"parentID":"gNms4aTjhR3vLDsTLhNtuWdv6S6xpA6vLjPB53uWSYRxxi3b", | ||
"timestamp":1750694509, | ||
"pChainHeight":0, | ||
"certificate":"MIIFNzCCAx8CCQC687XFxtDRSjANBgkqhkiG9w0BAQsFADB/MQswCQYDVQQGEwJVUzELMAkGA1UECAwCTlkxDzANBgNVBAcMBkl0aGFjYTEQMA4GA1UECgwHQXZhbGFiczEOMAwGA1UECwwFR2Vja28xDDAKBgNVBAMMA2F2YTEiMCAGCSqGSIb3DQEJARYTc3RlcGhlbkBhdmFsYWJzLm9yZzAgFw0xOTA3MDIxNjEyMTlaGA8zMDE5MDcxMDE2MTIxOVowOjELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAk5ZMRAwDgYDVQQKDAdBdmFsYWJzMQwwCgYDVQQDDANhdmEwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDdToR60na6NuR9iSAUMyzPXJNMWVQbLyT5/iZCiJ3BB4YWMBhfxpJWJiWXcM+znDgpJuyCEeh5Dp6ZY3Fe7k6Hht6FmFpDjwnjpQmdkEKUg00G+ElPTp/UsmsPL+JAswPqBZWpMBS3dsXQNunMMtMGlrf5S0l6XX4y7kc/GTxYgveWZ9JtR/m2KNer+wjgBHqJ4rPqnHB30sDYPZg91Cz1Ak8Bb2w2I108zQVgKK6eIqNKXJJ/4pizSZdU4920wMxYBpnfDAchnxei9U/v3QbT7eKUI2fGr+hOWTIWU80+VeOBt8a6P4sS9AQh5/6G8qwmAqO3YQ9dxN82iu/H3+N+GGa/M0r5rEWrzwIuFhwKvyQcpPRBm2yQnBnhL9G5kN6n4OBM0KsgZ3CYlHZSg4eWcNgBt1WCFsQc7vfUFaJnr8QP3pF4V/4Bok7wTO5HN0A1EYEVYuX53NGnrKVe+Fg9+xMOgXPWkUNqdvpI9ZbV3Z0S5866qF3/vBZrhgCrKc5E/vMexBRe8Ki4wKqONVhi9WGUcRHvFEikc+7VrPj0YaG6zVLd+uOAJN81fKOPYo4X4sZrMyPYl3OjGtMhfV4KvCaLEr1duOklqO6cCvGQ8iAlLVy3VJyW5GJ0D0KyiAir4VNdAJKo1ZgiGivJLWulTfjUifCN9o115AiqJxiqwwIDAQABMA0GCSqGSIb3DQEBCwUAA4ICAQCQOdwD7eRIxBvbQHUc+m0TRzEa17BCfck1Y2WwN3TZXDGSkPVE0uujA8SL3qi8/CTLGRqI9U3gRZJf+tJPBF/P021PEmyaFTS4htxcDxTxuZv2jCo9+XhUEyvRWitTmoy1esq3mkotVQHeTmQvwCsQJAhctVA/hRdJwmMPs1B8QxOUI6BqSOBHa9CsXIzVOFv8FqE91PZA2ns30sKQYrrnbH99apfF5WglLUoyPwxf2e3AACh7beEdk45ivvKwi5Jk8nr85KDHYPlqkr0bd9Ehl8xplaNBdMPeRufqBDlztjcLJ3womnrt95gQMeSoLHY3UNsIRjbj43zImu7q9v/DD9ppQpu26aRDRmBNgLZA9GM5XnbZRFi3VxLyqasGcSzaHwz5c7vOBOkOdlqcQzISRvWDxiN1HkAL+hkiQCuMchgORAgMwzPooa8rfWtLIpOXMpwuVGb/8rGNLEPovoCK9z6c+WZ+zkRo4+3TQkOMY66Xht7rAhly3ler+Tyg6a5jXT92WKC/MXBYAy2ZQNoy204kNKevcH7R2cSkxITd3n5EacNy5MAtCNIk7JweLCh9rLrLUBt+i4n44sP+LVhfWHemngA8CoF4n6eQ0pp0ixZTen0j4uN0G2Nf+JeGMlqoObLWdIOdH/pbDppXGoZaKKDd7+bA74Fle5Uh7+1e3A==", | ||
"block":"+QNw+QKYoFe0OHP1nW4P9JOQnoNzUC6qgo8OtNfb6Zm4Vfm4ldiMoB3MTejex116q4W1Z7bM1BrTEkUblIp0E/ChQv1A1JNHlAEAAAAAAAAAAAAAAAAAAAAAAAAAoGhdzXMedsLmpQPfV1mrEbMk8DyPJgkGN61NuyatVSL7oE77qnZEMeujlrntulL1lKZmBHNDJ2GTHJi0nvAEZ7h+oNlbZzgY+kk97sQU4B5hDZfuKHyUIcjv9BArFkfBoYTkuQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEMg+ThwIKkEIRoWXptuFYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIgAAAAAAAAAAKBW6B8XG8xVpv+DReaSwPhuW0jgG5lsrcABYi+142O0IYQ7msoAgICAgKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPjQ+GYQhTRjC4oAglIIlI25fHzs4knCuYvcAibMTCpXv1L8AYCCCpWgfvDG1UyDlkjqbP4ZHDfvxbqdkRVpXgYYcLYBwc5kfnWgPgZkWcsIU6jWf3t3d1NRWyzmJ1U6TZtRsGrWvfMQK474ZhGFNGMLigCCUgiUjbl8fOziScK5i9wCJsxMKle/UvwBgIIKlqA6HBjup31PCKKeSCRCyi8r61vIVo4naEcOvbauBTgkJKBuIF7y4Cc8SB8uKKYOUEV126BxRghgGIDYeQapjeQbs8CAgA=="}, | ||
"signature":"v8x0g+LFOcLZJaG07tZeLL+uOeKEvoLXfuhsB40aHU9U2MRsZpXWYZpYkTfqvNSo6TyUOUxNg0WLEiWYudafSfDJ5ht0atRtkXEMNHXJdZXRfD7xqox+hG/YojG9toaHogjudSzWTs+GKIvsYQaIcI401U7LFepBeOHauKdBCa4VFCQKCM3a6dyOxtsXz+/8LQgU6QjldnZwDG+jpLvhyE5Tf9fS8oSRv5zjxeVzCAJ8GYo1R62aI9NlNZsMcJwmCr9qBM3Fm8tKZQBsZsnMK+yuSeknWi81FyYHYqe0xkYSFYNZCiXedKkkpmpD0rGm8JrftmTlUvwLGyYFlN9XeVszTBJWJ+ESYG14R5D2kW3LYQ8eEKQk8O+CRM3n0vBjHgJbKNVPiiQAPzeStCCh7rYqiiGifp634yeLfhTfx4TnNs4vrSIOqcLZfpi0Uf06IStrhjp3nVWoDq0oTkngVWeSZj44MW56MaxrGRXpah3VCSTEj/u31G3zY7qjyBhEV0EVd6p5PLOpre9zMB7OyPdWH2CmGH8T7TTS4XVqeVn9WxCk91PQfdkAIt4qLqQB4lFs2ReipIwDDizAst+qXeyCrxj2dyRipaWKnRKHcrRfeCyKGFRWQVjtdVMcwC0gUBcN6VFHqOsrg2T7g9dHIr7mjhZUzzFNYpWZ43lWF/8=" | ||
} | ||
}, | ||
"encoding":"json" | ||
}, | ||
"id":1 | ||
} | ||
``` |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -7,8 +7,10 @@ import ( | |
"context" | ||
"errors" | ||
"fmt" | ||
"net/http" | ||
"time" | ||
|
||
"github.com/gorilla/rpc/v2" | ||
"github.com/prometheus/client_golang/prometheus" | ||
"go.uber.org/zap" | ||
|
||
|
@@ -24,6 +26,7 @@ import ( | |
"github.com/ava-labs/avalanchego/snow/engine/common" | ||
"github.com/ava-labs/avalanchego/snow/engine/snowman/block" | ||
"github.com/ava-labs/avalanchego/utils/constants" | ||
"github.com/ava-labs/avalanchego/utils/json" | ||
"github.com/ava-labs/avalanchego/utils/math" | ||
"github.com/ava-labs/avalanchego/utils/timer/mockable" | ||
"github.com/ava-labs/avalanchego/utils/units" | ||
|
@@ -251,6 +254,25 @@ func (vm *VM) Shutdown(ctx context.Context) error { | |
return vm.ChainVM.Shutdown(ctx) | ||
} | ||
|
||
// overriddes ChainVM.CreateHandlers to expose the proposervm API path | ||
func (vm *VM) CreateHandlers(ctx context.Context) (map[string]http.Handler, error) { | ||
handlers, err := vm.ChainVM.CreateHandlers(ctx) | ||
if err != nil { | ||
return nil, fmt.Errorf("failed to create inner VM handlers: %w", err) | ||
} | ||
|
||
server := rpc.NewServer() | ||
server.RegisterCodec(json.NewCodec(), "application/json") | ||
server.RegisterCodec(json.NewCodec(), "application/json;charset=UTF-8") | ||
err = server.RegisterService(&ProposerAPI{vm}, "proposervm") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why don't we have these two also similar to the platformVM?
Any thoughts about this? |
||
if err != nil { | ||
return nil, fmt.Errorf("failed to register proposervm service: %w", err) | ||
} | ||
handlers["/proposervm"] = server | ||
|
||
return handlers, nil | ||
} | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. what about a unit test that invokes this API? |
||
func (vm *VM) SetState(ctx context.Context, newState snow.State) error { | ||
if err := vm.ChainVM.SetState(ctx, newState); err != nil { | ||
return err | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we add unit tests for this file?