Modify test.md
This commit is contained in:
parent
645f0d0f9f
commit
796b3ebff6
302
test.md
302
test.md
@ -1,22 +1,10 @@
|
||||
## Basic types
|
||||
|
||||
### Error
|
||||
|
||||
```proto
|
||||
message Error {
|
||||
string code = 1; // One of a server-defined set of error codes.
|
||||
string message = 2; // A human-readable representation of the error.
|
||||
string target = 3; // The target of the error.
|
||||
repeated Error details = 4; // An array of details about specific errors that led to this reported error.
|
||||
}
|
||||
```
|
||||
|
||||
### ClientVersionResponse
|
||||
|
||||
```proto
|
||||
message ClientVersionResponse {
|
||||
Error error = 1;
|
||||
string version = 2; // 节点客户端版本
|
||||
string version = 1; // 节点客户端版本
|
||||
}
|
||||
```
|
||||
|
||||
@ -66,24 +54,6 @@ message Block {
|
||||
}
|
||||
```
|
||||
|
||||
### BlockResponse
|
||||
|
||||
```proto
|
||||
message BlockResponse {
|
||||
Error error = 1;
|
||||
Block block = 2;
|
||||
}
|
||||
```
|
||||
|
||||
### TransactionResponse
|
||||
|
||||
```proto
|
||||
message TransactionResponse {
|
||||
Error error = 1;
|
||||
Transaction transaction = 2;
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Transaction ledger API
|
||||
@ -113,7 +83,6 @@ bdchain.api.ClientVersionResponse
|
||||
|
||||
**Response**
|
||||
```yaml
|
||||
error: (empty Error object)
|
||||
version: 'TxLedgerGo/v0.0.1alpha/darwin/go1.11'
|
||||
```
|
||||
|
||||
@ -133,7 +102,7 @@ message CreateLedgerRequest {
|
||||
|
||||
```proto
|
||||
message CreateLedgerResponse {
|
||||
Error error = 1;
|
||||
bool ok = 1;
|
||||
}
|
||||
```
|
||||
|
||||
@ -148,7 +117,7 @@ name: 'test'
|
||||
|
||||
**Response**
|
||||
```yaml
|
||||
error: (empty Error object)
|
||||
ok: true
|
||||
```
|
||||
|
||||
##### 2
|
||||
@ -164,13 +133,11 @@ On the wire:
|
||||
name: '' (defualt value)
|
||||
```
|
||||
|
||||
**Response**
|
||||
**Error**
|
||||
```yaml
|
||||
error:
|
||||
code: 'BadArgument'
|
||||
message: 'name must not be empty'
|
||||
target: 'name'
|
||||
details:
|
||||
code: Code.InvalidArgument
|
||||
message: 'name must not be empty'
|
||||
details:
|
||||
```
|
||||
|
||||
---
|
||||
@ -187,8 +154,7 @@ google.protobuf.Empty
|
||||
|
||||
```proto
|
||||
message GetLedgersResponse {
|
||||
Error error = 1;
|
||||
repeated string ledgers = 2;
|
||||
repeated string ledgers = 1;
|
||||
}
|
||||
```
|
||||
|
||||
@ -203,7 +169,6 @@ message GetLedgersResponse {
|
||||
|
||||
**Response**
|
||||
```yaml
|
||||
error: (empty Error object)
|
||||
ledgers:
|
||||
- 'first'
|
||||
- 'second'
|
||||
@ -232,9 +197,8 @@ message SendTransactionRequest {
|
||||
#### Response
|
||||
|
||||
```proto
|
||||
message SendTransactionResponse {
|
||||
Error error = 1;
|
||||
bytes hash = 2;
|
||||
message SendTransactionResponse {
|
||||
bytes hash = 1;
|
||||
}
|
||||
```
|
||||
|
||||
@ -254,7 +218,6 @@ transaction:
|
||||
|
||||
**Response**
|
||||
```yaml
|
||||
error: (empty Error object)
|
||||
hash: 0xd15ea5edd15ea5edd15ea5edd15ea5edd15ea5edd15ea5edd15ea5edd15ea5ed (in bytes)
|
||||
```
|
||||
|
||||
@ -270,22 +233,17 @@ transaction:
|
||||
data: null (in bytes)
|
||||
```
|
||||
|
||||
**Response**
|
||||
**Error**
|
||||
```yaml
|
||||
error:
|
||||
code: 'BadArgument'
|
||||
message: 'Multiple errors in transaction'
|
||||
target: 'transaction'
|
||||
details:
|
||||
- code: 'EmptyValue'
|
||||
message: 'from must not be empty'
|
||||
target: 'from'
|
||||
details:
|
||||
- code: 'MalformedAddress'
|
||||
message: 'to must be a valid 32-byte address'
|
||||
target: 'to'
|
||||
details:
|
||||
hash: (empty bytes, default value)
|
||||
code: Code.InvalidArgument
|
||||
message: 'Multiple errors in transaction'
|
||||
details:
|
||||
- code: Code.InvalidArgument
|
||||
message: 'from must not be empty'
|
||||
details:
|
||||
- code: Code.InvalidArgument
|
||||
message: 'to must be a valid 32-byte address'
|
||||
details:
|
||||
```
|
||||
|
||||
---
|
||||
@ -317,7 +275,6 @@ bdchain.api.ClientVersionResponse
|
||||
|
||||
**Response**
|
||||
```yaml
|
||||
error: (empty Error object)
|
||||
version: 'AcChainGo/v0.0.1alpha/darwin/go1.11'
|
||||
```
|
||||
|
||||
@ -337,8 +294,7 @@ message BlockNumberRequest {
|
||||
|
||||
```proto
|
||||
message BlockNumberResponse {
|
||||
Error error = 1;
|
||||
uint64 block_number = 2;
|
||||
uint64 block_number = 1;
|
||||
}
|
||||
```
|
||||
|
||||
@ -353,7 +309,6 @@ ledger: 'test'
|
||||
|
||||
**Response**
|
||||
```yaml
|
||||
error: (empty Error object)
|
||||
block_number: 2018
|
||||
```
|
||||
|
||||
@ -370,14 +325,11 @@ On the wire:
|
||||
ledger: '' (defualt value)
|
||||
```
|
||||
|
||||
**Response**
|
||||
**Error**
|
||||
```yaml
|
||||
error:
|
||||
code: 'BadArgument'
|
||||
message: 'name must not be empty'
|
||||
target: 'name'
|
||||
details:
|
||||
block_number: 0 (default value)
|
||||
code: Code.InvalidArgument
|
||||
message: 'name must not be empty'
|
||||
details:
|
||||
```
|
||||
|
||||
---
|
||||
@ -397,7 +349,7 @@ message GetBlockByNumberRequest {
|
||||
#### Response
|
||||
|
||||
```
|
||||
bdchain.api.BlockResponse
|
||||
Block
|
||||
```
|
||||
|
||||
#### Test cases
|
||||
@ -413,41 +365,39 @@ full_transaction: true
|
||||
|
||||
**Response**
|
||||
```yaml
|
||||
error: (empty Error object)
|
||||
block:
|
||||
number: 2018
|
||||
hash: 0xdeadcodedeadcodedeadcodedeadcodedeadcodedeadcodedeadcodedeadcode (in bytes)
|
||||
parent_hash: 0xbabefacebabefacebabefacebabefacebabefacebabefacebabefacebabeface (in bytes)
|
||||
witness: 0x1fee1bad1fee1bad1fee1bad1fee1bad1fee1bad1fee1bad1fee1bad1fee1bad (in bytes)
|
||||
timestamp: 2018050400000
|
||||
size: 20180504
|
||||
transactions_root: 0x5obada555obada555obada555obada555obada555obada555obada555obada55 (in bytes)
|
||||
transactions:
|
||||
- block_number: 2018
|
||||
block_hash: 0xdeadcodedeadcodedeadcodedeadcodedeadcodedeadcodedeadcodedeadcode (in bytes)
|
||||
index: 0
|
||||
hash: 0x0404040404040404040404040404040404040404040404040404040404040404 (in bytes)
|
||||
type: TransactionType.RECORD
|
||||
from: 0xf00dcafef00dcafef00dcafef00dcafef00dcafef00dcafef00dcafef00dcafe (in bytes)
|
||||
nonce: 2018
|
||||
to: 0xf00dcafef00dcafef00dcafef00dcafef00dcafef00dcafef00dcafef00dcafe (in bytes)
|
||||
data: 0xdeadbeef (in bytes)
|
||||
v: 0x25 (in bytes)
|
||||
r: 0x1b5e176d927f8e9ab405058b2d2457392da3e20f328b16ddabcebc33eaac5fea (in bytes)
|
||||
s: 0x4ba69724e8f69de52f0125ad8b3c5c2cef33019bac3249e2c0a2192766d1721c (in bytes)
|
||||
- block_number: 2018
|
||||
block_hash: 0xdeadcodedeadcodedeadcodedeadcodedeadcodedeadcodedeadcodedeadcode (in bytes)
|
||||
index: 1
|
||||
hash: 0x1313131313131313131313131313131313131313131313131313131313131313 (in bytes)
|
||||
type: TransactionType.MESSAGE
|
||||
from: 0xf00dcafef00dcafef00dcafef00dcafef00dcafef00dcafef00dcafef00dcafe (in bytes)
|
||||
nonce: 2019
|
||||
to: 0xfeedbabefeedbabefeedbabefeedbabefeedbabefeedbabefeedbabefeedbabe (in bytes)
|
||||
data: (empty bytes, default value)
|
||||
v: 0x25 (in bytes)
|
||||
r: 0x1b5e176d927f8e9ab405058b2d2457392da3e20f328b16ddabcebc33eaac5fea (in bytes)
|
||||
s: 0x4ba69724e8f69de52f0125ad8b3c5c2cef33019bac3249e2c0a2192766d1721c (in bytes)
|
||||
transaction_hashes:
|
||||
number: 2018
|
||||
hash: 0xdeadcodedeadcodedeadcodedeadcodedeadcodedeadcodedeadcodedeadcode (in bytes)
|
||||
parent_hash: 0xbabefacebabefacebabefacebabefacebabefacebabefacebabefacebabeface (in bytes)
|
||||
witness: 0x1fee1bad1fee1bad1fee1bad1fee1bad1fee1bad1fee1bad1fee1bad1fee1bad (in bytes)
|
||||
timestamp: 2018050400000
|
||||
size: 20180504
|
||||
transactions_root: 0x5obada555obada555obada555obada555obada555obada555obada555obada55 (in bytes)
|
||||
transactions:
|
||||
- block_number: 2018
|
||||
block_hash: 0xdeadcodedeadcodedeadcodedeadcodedeadcodedeadcodedeadcodedeadcode (in bytes)
|
||||
index: 0
|
||||
hash: 0x0404040404040404040404040404040404040404040404040404040404040404 (in bytes)
|
||||
type: TransactionType.RECORD
|
||||
from: 0xf00dcafef00dcafef00dcafef00dcafef00dcafef00dcafef00dcafef00dcafe (in bytes)
|
||||
nonce: 2018
|
||||
to: 0xf00dcafef00dcafef00dcafef00dcafef00dcafef00dcafef00dcafef00dcafe (in bytes)
|
||||
data: 0xdeadbeef (in bytes)
|
||||
v: 0x25 (in bytes)
|
||||
r: 0x1b5e176d927f8e9ab405058b2d2457392da3e20f328b16ddabcebc33eaac5fea (in bytes)
|
||||
s: 0x4ba69724e8f69de52f0125ad8b3c5c2cef33019bac3249e2c0a2192766d1721c (in bytes)
|
||||
- block_number: 2018
|
||||
block_hash: 0xdeadcodedeadcodedeadcodedeadcodedeadcodedeadcodedeadcodedeadcode (in bytes)
|
||||
index: 1
|
||||
hash: 0x1313131313131313131313131313131313131313131313131313131313131313 (in bytes)
|
||||
type: TransactionType.MESSAGE
|
||||
from: 0xf00dcafef00dcafef00dcafef00dcafef00dcafef00dcafef00dcafef00dcafe (in bytes)
|
||||
nonce: 2019
|
||||
to: 0xfeedbabefeedbabefeedbabefeedbabefeedbabefeedbabefeedbabefeedbabe (in bytes)
|
||||
data: (empty bytes, default value)
|
||||
v: 0x25 (in bytes)
|
||||
r: 0x1b5e176d927f8e9ab405058b2d2457392da3e20f328b16ddabcebc33eaac5fea (in bytes)
|
||||
s: 0x4ba69724e8f69de52f0125ad8b3c5c2cef33019bac3249e2c0a2192766d1721c (in bytes)
|
||||
transaction_hashes:
|
||||
```
|
||||
|
||||
##### 2
|
||||
@ -469,19 +419,17 @@ full_transaction: false (defualt value)
|
||||
|
||||
**Response**
|
||||
```yaml
|
||||
error: (empty Error object)
|
||||
block:
|
||||
number: 2018
|
||||
hash: 0xdeadcodedeadcodedeadcodedeadcodedeadcodedeadcodedeadcodedeadcode (in bytes)
|
||||
parent_hash: 0xbabefacebabefacebabefacebabefacebabefacebabefacebabefacebabeface (in bytes)
|
||||
witness: 0x1fee1bad1fee1bad1fee1bad1fee1bad1fee1bad1fee1bad1fee1bad1fee1bad (in bytes)
|
||||
timestamp: 2018050400000
|
||||
size: 20180504
|
||||
transactions_root: 0x5obada555obada555obada555obada555obada555obada555obada555obada55 (in bytes)
|
||||
transactions:
|
||||
transaction_hashes:
|
||||
- 0x0404040404040404040404040404040404040404040404040404040404040404 (in bytes)
|
||||
- 0x1313131313131313131313131313131313131313131313131313131313131313 (in bytes)
|
||||
number: 2018
|
||||
hash: 0xdeadcodedeadcodedeadcodedeadcodedeadcodedeadcodedeadcodedeadcode (in bytes)
|
||||
parent_hash: 0xbabefacebabefacebabefacebabefacebabefacebabefacebabefacebabeface (in bytes)
|
||||
witness: 0x1fee1bad1fee1bad1fee1bad1fee1bad1fee1bad1fee1bad1fee1bad1fee1bad (in bytes)
|
||||
timestamp: 2018050400000
|
||||
size: 20180504
|
||||
transactions_root: 0x5obada555obada555obada555obada555obada555obada555obada555obada55 (in bytes)
|
||||
transactions:
|
||||
transaction_hashes:
|
||||
- 0x0404040404040404040404040404040404040404040404040404040404040404 (in bytes)
|
||||
- 0x1313131313131313131313131313131313131313131313131313131313131313 (in bytes)
|
||||
```
|
||||
|
||||
---
|
||||
@ -501,7 +449,7 @@ message GetBlockByHashRequest {
|
||||
#### Response
|
||||
|
||||
```
|
||||
bdchain.api.BlockResponse
|
||||
Block
|
||||
```
|
||||
|
||||
#### Test cases
|
||||
@ -517,19 +465,17 @@ full_transaction: false
|
||||
|
||||
**Response**
|
||||
```yaml
|
||||
error: (empty Error object)
|
||||
block:
|
||||
number: 2018
|
||||
hash: 0xdeadcodedeadcodedeadcodedeadcodedeadcodedeadcodedeadcodedeadcode (in bytes)
|
||||
parent_hash: 0xbabefacebabefacebabefacebabefacebabefacebabefacebabefacebabeface (in bytes)
|
||||
witness: 0x1fee1bad1fee1bad1fee1bad1fee1bad1fee1bad1fee1bad1fee1bad1fee1bad (in bytes)
|
||||
timestamp: 2018050400000
|
||||
size: 20180504
|
||||
transactions_root: 0x5obada555obada555obada555obada555obada555obada555obada555obada55 (in bytes)
|
||||
transactions:
|
||||
transaction_hashes:
|
||||
- 0x0404040404040404040404040404040404040404040404040404040404040404 (in bytes)
|
||||
- 0x1313131313131313131313131313131313131313131313131313131313131313 (in bytes)
|
||||
number: 2018
|
||||
hash: 0xdeadcodedeadcodedeadcodedeadcodedeadcodedeadcodedeadcodedeadcode (in bytes)
|
||||
parent_hash: 0xbabefacebabefacebabefacebabefacebabefacebabefacebabefacebabeface (in bytes)
|
||||
witness: 0x1fee1bad1fee1bad1fee1bad1fee1bad1fee1bad1fee1bad1fee1bad1fee1bad (in bytes)
|
||||
timestamp: 2018050400000
|
||||
size: 20180504
|
||||
transactions_root: 0x5obada555obada555obada555obada555obada555obada555obada555obada55 (in bytes)
|
||||
transactions:
|
||||
transaction_hashes:
|
||||
- 0x0404040404040404040404040404040404040404040404040404040404040404 (in bytes)
|
||||
- 0x1313131313131313131313131313131313131313131313131313131313131313 (in bytes)
|
||||
```
|
||||
|
||||
---
|
||||
@ -548,7 +494,7 @@ message GetTransactionByHashRequest {
|
||||
#### Response
|
||||
|
||||
```
|
||||
bdchain.api.TransactionResponse
|
||||
Transaction
|
||||
```
|
||||
|
||||
#### Test cases
|
||||
@ -563,20 +509,18 @@ hash: 0x0404040404040404040404040404040404040404040404040404040404040404 (in byt
|
||||
|
||||
**Response**
|
||||
```yaml
|
||||
error: (empty Error object)
|
||||
transaction:
|
||||
block_number: 2018
|
||||
block_hash: 0xdeadcodedeadcodedeadcodedeadcodedeadcodedeadcodedeadcodedeadcode (in bytes)
|
||||
index: 0
|
||||
hash: 0x0404040404040404040404040404040404040404040404040404040404040404 (in bytes)
|
||||
type: TransactionType.RECORD
|
||||
from: 0xf00dcafef00dcafef00dcafef00dcafef00dcafef00dcafef00dcafef00dcafe (in bytes)
|
||||
nonce: 2018
|
||||
to: 0xf00dcafef00dcafef00dcafef00dcafef00dcafef00dcafef00dcafef00dcafe (in bytes)
|
||||
data: 0xdeadbeef (in bytes)
|
||||
v: 0x25 (in bytes)
|
||||
r: 0x1b5e176d927f8e9ab405058b2d2457392da3e20f328b16ddabcebc33eaac5fea (in bytes)
|
||||
s: 0x4ba69724e8f69de52f0125ad8b3c5c2cef33019bac3249e2c0a2192766d1721c (in bytes)
|
||||
block_number: 2018
|
||||
block_hash: 0xdeadcodedeadcodedeadcodedeadcodedeadcodedeadcodedeadcodedeadcode (in bytes)
|
||||
index: 0
|
||||
hash: 0x0404040404040404040404040404040404040404040404040404040404040404 (in bytes)
|
||||
type: TransactionType.RECORD
|
||||
from: 0xf00dcafef00dcafef00dcafef00dcafef00dcafef00dcafef00dcafef00dcafe (in bytes)
|
||||
nonce: 2018
|
||||
to: 0xf00dcafef00dcafef00dcafef00dcafef00dcafef00dcafef00dcafef00dcafe (in bytes)
|
||||
data: 0xdeadbeef (in bytes)
|
||||
v: 0x25 (in bytes)
|
||||
r: 0x1b5e176d927f8e9ab405058b2d2457392da3e20f328b16ddabcebc33eaac5fea (in bytes)
|
||||
s: 0x4ba69724e8f69de52f0125ad8b3c5c2cef33019bac3249e2c0a2192766d1721c (in bytes)
|
||||
```
|
||||
|
||||
---
|
||||
@ -596,7 +540,7 @@ message GetTransactionByBlockNumberAndIndexRequest {
|
||||
#### Response
|
||||
|
||||
```
|
||||
bdchain.api.TransactionResponse
|
||||
Transaction
|
||||
```
|
||||
|
||||
#### Test cases
|
||||
@ -612,20 +556,18 @@ index: 0
|
||||
|
||||
**Response**
|
||||
```yaml
|
||||
error: (empty Error object)
|
||||
transaction:
|
||||
block_number: 2018
|
||||
block_hash: 0xdeadcodedeadcodedeadcodedeadcodedeadcodedeadcodedeadcodedeadcode (in bytes)
|
||||
index: 0
|
||||
hash: 0x0404040404040404040404040404040404040404040404040404040404040404 (in bytes)
|
||||
type: TransactionType.RECORD
|
||||
from: 0xf00dcafef00dcafef00dcafef00dcafef00dcafef00dcafef00dcafef00dcafe (in bytes)
|
||||
nonce: 2018
|
||||
to: 0xf00dcafef00dcafef00dcafef00dcafef00dcafef00dcafef00dcafef00dcafe (in bytes)
|
||||
data: 0xdeadbeef (in bytes)
|
||||
v: 0x25 (in bytes)
|
||||
r: 0x1b5e176d927f8e9ab405058b2d2457392da3e20f328b16ddabcebc33eaac5fea (in bytes)
|
||||
s: 0x4ba69724e8f69de52f0125ad8b3c5c2cef33019bac3249e2c0a2192766d1721c (in bytes)
|
||||
block_number: 2018
|
||||
block_hash: 0xdeadcodedeadcodedeadcodedeadcodedeadcodedeadcodedeadcodedeadcode (in bytes)
|
||||
index: 0
|
||||
hash: 0x0404040404040404040404040404040404040404040404040404040404040404 (in bytes)
|
||||
type: TransactionType.RECORD
|
||||
from: 0xf00dcafef00dcafef00dcafef00dcafef00dcafef00dcafef00dcafef00dcafe (in bytes)
|
||||
nonce: 2018
|
||||
to: 0xf00dcafef00dcafef00dcafef00dcafef00dcafef00dcafef00dcafef00dcafe (in bytes)
|
||||
data: 0xdeadbeef (in bytes)
|
||||
v: 0x25 (in bytes)
|
||||
r: 0x1b5e176d927f8e9ab405058b2d2457392da3e20f328b16ddabcebc33eaac5fea (in bytes)
|
||||
s: 0x4ba69724e8f69de52f0125ad8b3c5c2cef33019bac3249e2c0a2192766d1721c (in bytes)
|
||||
```
|
||||
|
||||
---
|
||||
@ -645,7 +587,7 @@ message GetTransactionByBlockHashAndIndexRequest {
|
||||
#### Response
|
||||
|
||||
```
|
||||
bdchain.api.TransactionResponse
|
||||
Transaction
|
||||
```
|
||||
|
||||
#### Test cases
|
||||
@ -661,18 +603,16 @@ index: 0
|
||||
|
||||
**Response**
|
||||
```yaml
|
||||
error: (empty Error object)
|
||||
transaction:
|
||||
block_number: 2018
|
||||
block_hash: 0xdeadcodedeadcodedeadcodedeadcodedeadcodedeadcodedeadcodedeadcode (in bytes)
|
||||
index: 0
|
||||
hash: 0x0404040404040404040404040404040404040404040404040404040404040404 (in bytes)
|
||||
type: TransactionType.RECORD
|
||||
from: 0xf00dcafef00dcafef00dcafef00dcafef00dcafef00dcafef00dcafef00dcafe (in bytes)
|
||||
nonce: 2018
|
||||
to: 0xf00dcafef00dcafef00dcafef00dcafef00dcafef00dcafef00dcafef00dcafe (in bytes)
|
||||
data: 0xdeadbeef (in bytes)
|
||||
v: 0x25 (in bytes)
|
||||
r: 0x1b5e176d927f8e9ab405058b2d2457392da3e20f328b16ddabcebc33eaac5fea (in bytes)
|
||||
s: 0x4ba69724e8f69de52f0125ad8b3c5c2cef33019bac3249e2c0a2192766d1721c (in bytes)
|
||||
block_number: 2018
|
||||
block_hash: 0xdeadcodedeadcodedeadcodedeadcodedeadcodedeadcodedeadcodedeadcode (in bytes)
|
||||
index: 0
|
||||
hash: 0x0404040404040404040404040404040404040404040404040404040404040404 (in bytes)
|
||||
type: TransactionType.RECORD
|
||||
from: 0xf00dcafef00dcafef00dcafef00dcafef00dcafef00dcafef00dcafef00dcafe (in bytes)
|
||||
nonce: 2018
|
||||
to: 0xf00dcafef00dcafef00dcafef00dcafef00dcafef00dcafef00dcafef00dcafe (in bytes)
|
||||
data: 0xdeadbeef (in bytes)
|
||||
v: 0x25 (in bytes)
|
||||
r: 0x1b5e176d927f8e9ab405058b2d2457392da3e20f328b16ddabcebc33eaac5fea (in bytes)
|
||||
s: 0x4ba69724e8f69de52f0125ad8b3c5c2cef33019bac3249e2c0a2192766d1721c (in bytes)
|
||||
```
|
||||
|
Loading…
x
Reference in New Issue
Block a user